@@ -107,7 +33,6 @@ export function PhaseTimelineDetailed({
const isActive = index === currentPhaseIndex
const isCompleted = phase.status === 'completed'
const isPast = index < currentPhaseIndex
- const colors = PHASE_COLORS[phase.id]
return (
@@ -118,7 +43,7 @@ export function PhaseTimelineDetailed({
className="flex-1 h-1"
style={{
background: isPast || isCompleted
- ? PHASE_COLORS[phases[index - 1].id].hex
+ ? phases[index - 1].color
: '#e2e8f0',
}}
/>
@@ -138,9 +63,9 @@ export function PhaseTimelineDetailed({
${isActive ? 'ring-4 ring-offset-2 shadow-lg' : ''}
`}
style={{
- backgroundColor: isActive || isCompleted || isPast ? colors.hex : '#e2e8f0',
+ backgroundColor: isActive || isCompleted || isPast ? phase.color : '#e2e8f0',
color: isActive || isCompleted || isPast ? 'white' : '#64748b',
- '--tw-ring-color': isActive ? `${colors.hex}40` : undefined,
+ '--tw-ring-color': isActive ? `${phase.color}40` : undefined,
} as React.CSSProperties}
>
{isCompleted ? (
@@ -152,7 +77,7 @@ export function PhaseTimelineDetailed({
{isActive && (
)}
@@ -161,7 +86,7 @@ export function PhaseTimelineDetailed({
)}
diff --git a/admin-v2/components/companion/lesson-mode/QuickActionsBar.tsx b/studio-v2/components/companion/lesson-mode/QuickActionsBar.tsx
similarity index 100%
rename from admin-v2/components/companion/lesson-mode/QuickActionsBar.tsx
rename to studio-v2/components/companion/lesson-mode/QuickActionsBar.tsx
diff --git a/admin-v2/components/companion/lesson-mode/ReflectionSection.tsx b/studio-v2/components/companion/lesson-mode/ReflectionSection.tsx
similarity index 100%
rename from admin-v2/components/companion/lesson-mode/ReflectionSection.tsx
rename to studio-v2/components/companion/lesson-mode/ReflectionSection.tsx
diff --git a/admin-v2/components/companion/lesson-mode/VisualPieTimer.tsx b/studio-v2/components/companion/lesson-mode/VisualPieTimer.tsx
similarity index 100%
rename from admin-v2/components/companion/lesson-mode/VisualPieTimer.tsx
rename to studio-v2/components/companion/lesson-mode/VisualPieTimer.tsx
diff --git a/admin-v2/components/companion/modals/FeedbackModal.tsx b/studio-v2/components/companion/modals/FeedbackModal.tsx
similarity index 100%
rename from admin-v2/components/companion/modals/FeedbackModal.tsx
rename to studio-v2/components/companion/modals/FeedbackModal.tsx
diff --git a/admin-v2/components/companion/modals/OnboardingModal.tsx b/studio-v2/components/companion/modals/OnboardingModal.tsx
similarity index 100%
rename from admin-v2/components/companion/modals/OnboardingModal.tsx
rename to studio-v2/components/companion/modals/OnboardingModal.tsx
diff --git a/admin-v2/components/companion/modals/SettingsModal.tsx b/studio-v2/components/companion/modals/SettingsModal.tsx
similarity index 100%
rename from admin-v2/components/companion/modals/SettingsModal.tsx
rename to studio-v2/components/companion/modals/SettingsModal.tsx
diff --git a/admin-v2/hooks/companion/index.ts b/studio-v2/hooks/companion/index.ts
similarity index 72%
rename from admin-v2/hooks/companion/index.ts
rename to studio-v2/hooks/companion/index.ts
index 85edd4c..8b85950 100644
--- a/admin-v2/hooks/companion/index.ts
+++ b/studio-v2/hooks/companion/index.ts
@@ -1,3 +1,2 @@
-export { useCompanionData } from './useCompanionData'
export { useLessonSession } from './useLessonSession'
export { useKeyboardShortcuts, useKeyboardShortcutHints } from './useKeyboardShortcuts'
diff --git a/admin-v2/hooks/companion/useKeyboardShortcuts.ts b/studio-v2/hooks/companion/useKeyboardShortcuts.ts
similarity index 100%
rename from admin-v2/hooks/companion/useKeyboardShortcuts.ts
rename to studio-v2/hooks/companion/useKeyboardShortcuts.ts
diff --git a/admin-v2/hooks/companion/useLessonSession.ts b/studio-v2/hooks/companion/useLessonSession.ts
similarity index 95%
rename from admin-v2/hooks/companion/useLessonSession.ts
rename to studio-v2/hooks/companion/useLessonSession.ts
index a0529cb..dff3aea 100644
--- a/admin-v2/hooks/companion/useLessonSession.ts
+++ b/studio-v2/hooks/companion/useLessonSession.ts
@@ -29,6 +29,7 @@ interface UseLessonSessionReturn {
templateId?: string
}) => void
endLesson: () => void
+ clearSession: () => void
pauseLesson: () => void
resumeLesson: () => void
extendTime: (minutes: number) => void
@@ -96,10 +97,11 @@ export function useLessonSession(
const now = Date.now()
const delta = Math.floor((now - lastTickRef.current) / 1000)
- lastTickRef.current = now
if (delta <= 0) return
+ lastTickRef.current = now
+
setSession((prev) => {
if (!prev) return null
@@ -138,7 +140,7 @@ export function useLessonSession(
useEffect(() => {
if (session?.status === 'in_progress' && !session.isPaused) {
lastTickRef.current = Date.now()
- timerRef.current = setInterval(tick, 100) // Update every 100ms for smooth animation
+ timerRef.current = setInterval(tick, 100)
} else {
if (timerRef.current) {
clearInterval(timerRef.current)
@@ -175,12 +177,10 @@ export function useLessonSession(
if (stored) {
try {
const parsed = JSON.parse(stored) as LessonSession
- // Only restore if session is not completed and not too old (< 24h)
const sessionTime = new Date(parsed.startTime).getTime()
const isRecent = Date.now() - sessionTime < 24 * 60 * 60 * 1000
if (parsed.status !== 'completed' && isRecent) {
- // Pause the restored session
setSession({ ...parsed, isPaused: true })
}
} catch {
@@ -197,7 +197,6 @@ export function useLessonSession(
topic?: string
templateId?: string
}) => {
- // Find template durations
let durations = DEFAULT_PHASE_DURATIONS
if (data.templateId) {
const template = SYSTEM_TEMPLATES.find((t) => t.templateId === data.templateId)
@@ -253,6 +252,11 @@ export function useLessonSession(
onLessonComplete?.(completedSession)
}, [session, onLessonComplete])
+ const clearSession = useCallback(() => {
+ setSession(null)
+ localStorage.removeItem(STORAGE_KEYS.CURRENT_SESSION)
+ }, [])
+
const pauseLesson = useCallback(() => {
if (!session || session.isPaused) return
@@ -302,7 +306,6 @@ export function useLessonSession(
currentPhase.duration += minutes
- // Reset overtime trigger if we've added time
if (hasTriggeredOvertimeRef.current) {
const phaseDurationSeconds = currentPhase.duration * 60
if (currentPhase.actualTime < phaseDurationSeconds) {
@@ -325,7 +328,6 @@ export function useLessonSession(
const nextPhaseIndex = session.currentPhaseIndex + 1
- // Check if this was the last phase
if (nextPhaseIndex >= session.phases.length) {
endLesson()
return
@@ -336,14 +338,12 @@ export function useLessonSession(
const updatedPhases = [...prev.phases]
- // Complete current phase
updatedPhases[prev.currentPhaseIndex] = {
...updatedPhases[prev.currentPhaseIndex],
status: 'completed',
completedAt: new Date().toISOString(),
}
- // Start next phase
updatedPhases[nextPhaseIndex] = {
...updatedPhases[nextPhaseIndex],
status: 'active',
@@ -422,17 +422,12 @@ export function useLessonSession(
[session]
)
- // Clear session (for starting new)
- const clearSession = useCallback(() => {
- setSession(null)
- localStorage.removeItem(STORAGE_KEYS.CURRENT_SESSION)
- }, [])
-
return {
session,
timerState,
startLesson,
- endLesson: session?.status === 'completed' ? clearSession : endLesson,
+ endLesson,
+ clearSession,
pauseLesson,
resumeLesson,
extendTime,
diff --git a/admin-v2/lib/companion/constants.ts b/studio-v2/lib/companion/constants.ts
similarity index 100%
rename from admin-v2/lib/companion/constants.ts
rename to studio-v2/lib/companion/constants.ts
diff --git a/admin-v2/lib/companion/index.ts b/studio-v2/lib/companion/index.ts
similarity index 100%
rename from admin-v2/lib/companion/index.ts
rename to studio-v2/lib/companion/index.ts
diff --git a/admin-v2/lib/companion/types.ts b/studio-v2/lib/companion/types.ts
similarity index 100%
rename from admin-v2/lib/companion/types.ts
rename to studio-v2/lib/companion/types.ts
diff --git a/studio-v2/lib/i18n.ts b/studio-v2/lib/i18n.ts
index 3cb73aa..2a2428a 100644
--- a/studio-v2/lib/i18n.ts
+++ b/studio-v2/lib/i18n.ts
@@ -37,7 +37,7 @@ export const translations: Record
> = {
nav_worksheet_editor: 'Arbeitsblätter',
nav_worksheet_cleanup: 'Bereinigung',
nav_korrektur: 'Korrekturen',
- nav_compliance_pipeline: 'Compliance Pipeline',
+ nav_companion: 'Companion', nav_compliance_pipeline: 'Compliance Pipeline',
nav_meet: 'Meet',
nav_alerts: 'Alerts',
nav_alerts_b2b: 'B2B Alerts',
@@ -98,7 +98,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'Worksheets',
nav_worksheet_cleanup: 'Cleanup',
nav_korrektur: 'Corrections',
- nav_compliance_pipeline: 'Compliance Pipeline',
+ nav_companion: 'Companion', nav_compliance_pipeline: 'Compliance Pipeline',
nav_meet: 'Meet',
nav_alerts: 'Alerts',
nav_alerts_b2b: 'B2B Alerts',
@@ -145,7 +145,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'Çalışma Sayfaları',
nav_worksheet_cleanup: 'Temizleme',
nav_korrektur: 'Düzeltmeler',
- nav_compliance_pipeline: 'Uyum Boru Hattı',
+ nav_companion: 'Companion', nav_compliance_pipeline: 'Uyum Boru Hattı',
nav_meet: 'Meet',
nav_alerts: 'Uyarılar',
nav_alerts_b2b: 'B2B Uyarılar',
@@ -192,7 +192,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'أوراق العمل',
nav_worksheet_cleanup: 'تنظيف',
nav_korrektur: 'التصحيحات',
- nav_compliance_pipeline: 'خط أنابيب الامتثال',
+ nav_companion: 'المرافق', nav_compliance_pipeline: 'خط أنابيب الامتثال',
nav_meet: 'اجتماع',
nav_alerts: 'تنبيهات',
nav_alerts_b2b: 'تنبيهات الشركات',
@@ -239,7 +239,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'Рабочие листы',
nav_worksheet_cleanup: 'Очистка',
nav_korrektur: 'Проверки',
- nav_compliance_pipeline: 'Пайплайн соответствия',
+ nav_companion: 'Компаньон', nav_compliance_pipeline: 'Пайплайн соответствия',
nav_meet: 'Встреча',
nav_alerts: 'Оповещения',
nav_alerts_b2b: 'B2B оповещения',
@@ -286,7 +286,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'Робочі аркуші',
nav_worksheet_cleanup: 'Очищення',
nav_korrektur: 'Перевірки',
- nav_compliance_pipeline: 'Пайплайн відповідності',
+ nav_companion: 'Компаньйон', nav_compliance_pipeline: 'Пайплайн відповідності',
nav_meet: 'Зустріч',
nav_alerts: 'Сповіщення',
nav_alerts_b2b: 'B2B сповіщення',
@@ -333,7 +333,7 @@ export const translations: Record> = {
nav_worksheet_editor: 'Arkusze robocze',
nav_worksheet_cleanup: 'Czyszczenie',
nav_korrektur: 'Korekty',
- nav_compliance_pipeline: 'Pipeline zgodności',
+ nav_companion: 'Companion', nav_compliance_pipeline: 'Pipeline zgodności',
nav_meet: 'Spotkanie',
nav_alerts: 'Powiadomienia',
nav_alerts_b2b: 'Powiadomienia B2B',