fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
109
website/components/compliance/LanguageSwitch.tsx
Normal file
109
website/components/compliance/LanguageSwitch.tsx
Normal file
@@ -0,0 +1,109 @@
|
||||
'use client'
|
||||
|
||||
/**
|
||||
* LanguageSwitch Component
|
||||
*
|
||||
* Toggle button for switching between German and English terminology.
|
||||
* Stores preference in localStorage.
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Language, DEFAULT_LANGUAGE } from '@/lib/compliance-i18n'
|
||||
|
||||
interface LanguageSwitchProps {
|
||||
onChange?: (lang: Language) => void
|
||||
className?: string
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'breakpilot-compliance-lang'
|
||||
|
||||
export default function LanguageSwitch({ onChange, className = '' }: LanguageSwitchProps) {
|
||||
const [language, setLanguage] = useState<Language>(DEFAULT_LANGUAGE)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
// Load language from localStorage on mount
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
const stored = localStorage.getItem(STORAGE_KEY) as Language | null
|
||||
if (stored && (stored === 'de' || stored === 'en')) {
|
||||
setLanguage(stored)
|
||||
onChange?.(stored)
|
||||
}
|
||||
}, [onChange])
|
||||
|
||||
const toggleLanguage = () => {
|
||||
const newLang: Language = language === 'de' ? 'en' : 'de'
|
||||
setLanguage(newLang)
|
||||
localStorage.setItem(STORAGE_KEY, newLang)
|
||||
onChange?.(newLang)
|
||||
}
|
||||
|
||||
// Avoid hydration mismatch
|
||||
if (!mounted) {
|
||||
return (
|
||||
<div className={`h-8 w-16 bg-slate-100 rounded-full animate-pulse ${className}`} />
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleLanguage}
|
||||
className={`
|
||||
relative inline-flex items-center h-8 px-1
|
||||
bg-slate-100 hover:bg-slate-200
|
||||
rounded-full transition-colors
|
||||
focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
|
||||
${className}
|
||||
`}
|
||||
title={language === 'de' ? 'Switch to English' : 'Zu Deutsch wechseln'}
|
||||
aria-label={language === 'de' ? 'Switch to English' : 'Zu Deutsch wechseln'}
|
||||
>
|
||||
{/* DE Button */}
|
||||
<span
|
||||
className={`
|
||||
px-2 py-1 text-xs font-semibold rounded-full transition-all
|
||||
${language === 'de'
|
||||
? 'bg-white text-slate-900 shadow-sm'
|
||||
: 'text-slate-500 hover:text-slate-700'
|
||||
}
|
||||
`}
|
||||
>
|
||||
DE
|
||||
</span>
|
||||
|
||||
{/* EN Button */}
|
||||
<span
|
||||
className={`
|
||||
px-2 py-1 text-xs font-semibold rounded-full transition-all
|
||||
${language === 'en'
|
||||
? 'bg-white text-slate-900 shadow-sm'
|
||||
: 'text-slate-500 hover:text-slate-700'
|
||||
}
|
||||
`}
|
||||
>
|
||||
EN
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get and set compliance language
|
||||
*/
|
||||
export function useComplianceLanguage(): [Language, (lang: Language) => void] {
|
||||
const [language, setLanguage] = useState<Language>(DEFAULT_LANGUAGE)
|
||||
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem(STORAGE_KEY) as Language | null
|
||||
if (stored && (stored === 'de' || stored === 'en')) {
|
||||
setLanguage(stored)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setAndStore = (lang: Language) => {
|
||||
setLanguage(lang)
|
||||
localStorage.setItem(STORAGE_KEY, lang)
|
||||
}
|
||||
|
||||
return [language, setAndStore]
|
||||
}
|
||||
Reference in New Issue
Block a user