backend-lehrer (5 files): - alerts_agent/db/repository.py (992 → 5), abitur_docs_api.py (956 → 3) - teacher_dashboard_api.py (951 → 3), services/pdf_service.py (916 → 3) - mail/mail_db.py (987 → 6) klausur-service (5 files): - legal_templates_ingestion.py (942 → 3), ocr_pipeline_postprocess.py (929 → 4) - ocr_pipeline_words.py (876 → 3), ocr_pipeline_ocr_merge.py (616 → 2) - KorrekturPage.tsx (956 → 6) website (5 pages): - mail (985 → 9), edu-search (958 → 8), mac-mini (950 → 7) - ocr-labeling (946 → 7), audit-workspace (871 → 4) studio-v2 (5 files + 1 deleted): - page.tsx (946 → 5), MessagesContext.tsx (925 → 4) - korrektur (914 → 6), worksheet-cleanup (899 → 6) - useVocabWorksheet.ts (888 → 3) - Deleted dead page-original.tsx (934 LOC) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
70 lines
2.8 KiB
TypeScript
70 lines
2.8 KiB
TypeScript
import type { Contact } from './types'
|
|
|
|
export function formatMessageTime(timestamp: string): string {
|
|
const date = new Date(timestamp)
|
|
const now = new Date()
|
|
const diffMs = now.getTime() - date.getTime()
|
|
const diffMins = Math.floor(diffMs / 60000)
|
|
const diffHours = Math.floor(diffMs / 3600000)
|
|
const diffDays = Math.floor(diffMs / 86400000)
|
|
|
|
if (diffMins < 1) return 'Gerade eben'
|
|
if (diffMins < 60) return `${diffMins} Min.`
|
|
if (diffHours < 24) return `${diffHours} Std.`
|
|
if (diffDays === 1) return 'Gestern'
|
|
if (diffDays < 7) return `${diffDays} Tage`
|
|
|
|
return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })
|
|
}
|
|
|
|
export function formatMessageDate(timestamp: string): string {
|
|
const date = new Date(timestamp)
|
|
const now = new Date()
|
|
const diffDays = Math.floor((now.getTime() - date.getTime()) / 86400000)
|
|
|
|
if (diffDays === 0) return 'Heute'
|
|
if (diffDays === 1) return 'Gestern'
|
|
if (diffDays < 7) {
|
|
return date.toLocaleDateString('de-DE', { weekday: 'long' })
|
|
}
|
|
|
|
return date.toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' })
|
|
}
|
|
|
|
export function getContactInitials(name: string): string {
|
|
const parts = name.split(' ').filter(p => p.length > 0)
|
|
if (parts.length >= 2) {
|
|
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()
|
|
}
|
|
return name.slice(0, 2).toUpperCase()
|
|
}
|
|
|
|
export function getRoleLabel(role: Contact['role']): string {
|
|
const labels: Record<Contact['role'], string> = {
|
|
parent: 'Eltern',
|
|
teacher: 'Lehrkraft',
|
|
staff: 'Verwaltung',
|
|
student: 'Schueler/in'
|
|
}
|
|
return labels[role] || role
|
|
}
|
|
|
|
export function getRoleColor(role: Contact['role'], isDark: boolean): string {
|
|
const colors: Record<Contact['role'], { dark: string; light: string }> = {
|
|
parent: { dark: 'bg-blue-500/20 text-blue-300', light: 'bg-blue-100 text-blue-700' },
|
|
teacher: { dark: 'bg-purple-500/20 text-purple-300', light: 'bg-purple-100 text-purple-700' },
|
|
staff: { dark: 'bg-amber-500/20 text-amber-300', light: 'bg-amber-100 text-amber-700' },
|
|
student: { dark: 'bg-green-500/20 text-green-300', light: 'bg-green-100 text-green-700' }
|
|
}
|
|
return isDark ? colors[role].dark : colors[role].light
|
|
}
|
|
|
|
// Emoji categories for picker
|
|
export const emojiCategories = {
|
|
'Häufig': ['👍', '❤️', '😊', '😂', '🙏', '👏', '🎉', '✅', '📝', '📚'],
|
|
'Smileys': ['😀', '😃', '😄', '😁', '😅', '😂', '🤣', '😊', '😇', '🙂', '😉', '😌', '😍', '🥰', '😘'],
|
|
'Gesten': ['👍', '👎', '👌', '✌️', '🤞', '🤝', '👏', '🙌', '👋', '✋', '🤚', '🖐️', '🙏'],
|
|
'Symbole': ['❤️', '💙', '💚', '💛', '🧡', '💜', '✅', '❌', '⭐', '🌟', '💯', '📌', '📎'],
|
|
'Schule': ['📚', '📖', '📝', '✏️', '📓', '📕', '📗', '📘', '🎓', '🏫', '📅', '⏰', '🔔']
|
|
}
|