enhancements of the homepage in the guest pwa

This commit is contained in:
Codex Agent
2025-12-15 19:05:27 +01:00
parent 763af12617
commit f2473c6f6d
14 changed files with 568 additions and 207 deletions

View File

@@ -110,51 +110,54 @@ export default function EmotionPicker({
</div>
)}
<div
className={cn(
'grid gap-3 pb-2',
variant === 'standalone' ? 'grid-cols-2 sm:grid-cols-3' : 'grid-cols-2 sm:grid-cols-3'
)}
aria-label="Emotions"
>
{emotions.map((emotion) => {
// Localize name and description if they are JSON
const localize = (value: string | object, defaultValue: string = ''): string => {
if (typeof value === 'string' && value.startsWith('{')) {
try {
const data = JSON.parse(value as string);
return data.de || data.en || defaultValue || '';
} catch {
return value as string;
<div className="relative">
<div
className={cn(
'grid grid-rows-2 grid-flow-col auto-cols-[170px] sm:auto-cols-[190px] gap-3 overflow-x-auto pb-2 pr-12',
'scrollbar-thin scrollbar-thumb-muted scrollbar-track-transparent'
)}
aria-label="Emotions"
>
{emotions.map((emotion) => {
// Localize name and description if they are JSON
const localize = (value: string | object, defaultValue: string = ''): string => {
if (typeof value === 'string' && value.startsWith('{')) {
try {
const data = JSON.parse(value as string);
return data.de || data.en || defaultValue || '';
} catch {
return value as string;
}
}
}
return value as string;
};
return value as string;
};
const localizedName = localize(emotion.name, emotion.name);
const localizedDescription = localize(emotion.description || '', '');
return (
<button
key={emotion.id}
type="button"
onClick={() => handleEmotionSelect(emotion)}
className="group flex min-w-[180px] flex-col gap-2 rounded-2xl border border-white/40 bg-white/80 px-4 py-3 text-left shadow-sm transition hover:-translate-y-0.5 hover:border-pink-200 hover:shadow-md dark:border-gray-700/60 dark:bg-gray-900/70"
>
<div className="flex items-center gap-3">
<span className="text-2xl" aria-hidden>
{emotion.emoji}
</span>
<div className="flex-1 min-w-0">
<div className="font-medium text-sm text-foreground line-clamp-1">{localizedName}</div>
{localizedDescription && (
<div className="text-xs text-muted-foreground line-clamp-1">{localizedDescription}</div>
)}
const localizedName = localize(emotion.name, emotion.name);
const localizedDescription = localize(emotion.description || '', '');
return (
<button
key={emotion.id}
type="button"
onClick={() => handleEmotionSelect(emotion)}
className="group flex flex-col gap-2 rounded-2xl border border-muted/40 bg-white/80 px-4 py-3 text-left shadow-sm transition hover:-translate-y-0.5 hover:border-foreground/10 hover:shadow-md dark:border-gray-700/60 dark:bg-gray-900/70"
>
<div className="flex items-center gap-3">
<span className="text-2xl" aria-hidden>
{emotion.emoji}
</span>
<div className="flex-1 min-w-0">
<div className="font-medium text-sm text-foreground">{localizedName}</div>
{localizedDescription && (
<div className="text-xs text-muted-foreground line-clamp-2">{localizedDescription}</div>
)}
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground opacity-0 transition group-hover:opacity-100" />
</div>
<ChevronRight className="h-4 w-4 text-muted-foreground opacity-0 transition group-hover:opacity-100" />
</div>
</button>
);
})}
</button>
);
})}
</div>
<div className="pointer-events-none absolute inset-y-0 right-0 w-10 bg-gradient-to-l from-[var(--guest-background)] via-[var(--guest-background)]/90 to-transparent dark:from-black dark:via-black/80" aria-hidden />
</div>
{/* Skip option */}