257 lines
5.8 KiB
Vue

<script setup>
import { ref } from 'vue'
import { useCollaborationStore } from './stores/collaboration'
import CollaborativeInput from './components/CollaborativeInput.vue'
import CollaborativeSession from './components/CollaborativeSession.vue'
import TimelinePanel from './components/TimelinePanel.vue'
const collaborationStore = useCollaborationStore()
const showSession = ref(false)
const currentSessionId = ref(null)
function handleCollaborationCreated(session) {
currentSessionId.value = session.sessionId
showSession.value = true
}
function startNewCollaboration() {
collaborationStore.clearCurrentSession()
showSession.value = false
}
</script>
<template>
<div class="app">
<!-- Input Mode - Centered Full Screen -->
<div v-if="!showSession" class="input-container">
<CollaborativeInput @session-created="handleCollaborationCreated" />
</div>
<!-- Session Mode - Two Column Layout -->
<div v-else class="session-layout">
<!-- Left Sidebar: Timeline -->
<div class="timeline-sidebar">
<div class="sidebar-header">
<h2>Session Progress</h2>
<button @click="startNewCollaboration" class="new-btn-small" title="Start new session">
R
</button>
</div>
<!-- Timeline Panel -->
<TimelinePanel />
</div>
<!-- Right Content: Session -->
<div class="main-content">
<CollaborativeSession
v-if="currentSessionId"
:session-id="currentSessionId"
@session-completed="startNewCollaboration"
/>
</div>
</div>
</div>
</template>
<style>
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes float1 {
0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: 0.03; }
25% { transform: translate(100px, -100px) rotate(90deg); opacity: 0.05; }
50% { transform: translate(-50px, 150px) rotate(180deg); opacity: 0.03; }
75% { transform: translate(-100px, -50px) rotate(270deg); opacity: 0.04; }
}
@keyframes float2 {
0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: 0.04; }
25% { transform: translate(-120px, 80px) rotate(-90deg); opacity: 0.06; }
50% { transform: translate(80px, -120px) rotate(-180deg); opacity: 0.04; }
75% { transform: translate(120px, 100px) rotate(-270deg); opacity: 0.05; }
}
@keyframes float3 {
0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: 0.03; }
25% { transform: translate(-80px, -80px) rotate(45deg); opacity: 0.05; }
50% { transform: translate(100px, 100px) rotate(135deg); opacity: 0.03; }
75% { transform: translate(-100px, 80px) rotate(225deg); opacity: 0.04; }
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
</style>
<style scoped>
.app {
min-height: 100vh;
background: linear-gradient(-45deg, #0f0c29 0%, #302b63 25%, #24243e 50%, #302b63 75%, #0f0c29 100%);
background-size: 400% 400%;
animation: gradient-shift 15s ease infinite;
position: relative;
overflow: hidden;
}
.app::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 200%;
height: 200%;
background: radial-gradient(circle at 20% 50%, rgba(102, 126, 234, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 80%, rgba(118, 75, 162, 0.08) 0%, transparent 50%);
animation: float1 20s ease-in-out infinite;
pointer-events: none;
z-index: 0;
}
.app::after {
content: '';
position: fixed;
bottom: 0;
right: 0;
width: 300px;
height: 300px;
background: radial-gradient(circle, rgba(102, 126, 234, 0.12) 0%, transparent 70%);
animation: float2 25s ease-in-out infinite;
pointer-events: none;
z-index: 0;
border-radius: 50%;
}
.app > * {
position: relative;
z-index: 1;
}
.input-container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 2rem;
}
.session-layout {
display: grid;
grid-template-columns: 320px 1fr;
min-height: 100vh;
gap: 0;
}
.timeline-sidebar {
background: rgba(48, 43, 99, 0.4);
border-right: 1px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
padding: 1.5rem;
overflow-y: auto;
max-height: 100vh;
box-shadow: inset -1px 0 0 rgba(102, 126, 234, 0.2);
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.sidebar-header h2 {
font-size: 1.2rem;
margin: 0;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.new-btn-small {
width: 32px;
height: 32px;
padding: 0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
background: rgba(102, 126, 234, 0.6);
}
.new-btn-small:hover {
background: rgba(102, 126, 234, 0.9);
transform: rotate(20deg);
}
.timeline-content {
display: flex;
flex-direction: column;
gap: 1rem;
}
.main-content {
padding: 2rem;
overflow-y: auto;
max-height: 100vh;
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: rgba(102, 126, 234, 0.4);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(102, 126, 234, 0.6);
}
/* Mobile responsive */
@media (max-width: 1024px) {
.session-layout {
grid-template-columns: 250px 1fr;
}
.timeline-sidebar {
padding: 1rem;
}
.main-content {
padding: 1rem;
}
}
@media (max-width: 768px) {
.session-layout {
grid-template-columns: 1fr;
}
.timeline-sidebar {
border-right: none;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
max-height: none;
}
.main-content {
max-height: none;
}
}
</style>