fix: replace emoji flags with SVG dropdown, complete Home's third row
Language switcher was two inline emoji-flag buttons -- emoji flag rendering is inconsistent across OS/browsers (some render as two-letter country codes instead of a flag). Replaced with hand-rolled inline SVG flags (no new dependency for two locales) inside a proper dropdown menu, trigger showing the current language's flag. Also added a 9th Home highlight (personalized recommendations, same copy already written for the Features page) so the lg:grid-cols-3 feature grid's last row has 3 items instead of 2. v0.48.2
This commit is contained in:
@@ -1,12 +1,20 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Check, Globe } from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { MARKETING_LOCALE_COOKIE } from "@/lib/marketing-locale-cookie";
|
||||
import type { Locale } from "@/lib/i18n/provider";
|
||||
import { FlagGB, FlagFR } from "./flag-icons";
|
||||
|
||||
const OPTIONS: { code: Locale; flag: string; label: string }[] = [
|
||||
{ code: "en", flag: "🇬🇧", label: "English" },
|
||||
{ code: "fr", flag: "🇫🇷", label: "Français" },
|
||||
const OPTIONS: { code: Locale; Flag: typeof FlagGB; label: string }[] = [
|
||||
{ code: "en", Flag: FlagGB, label: "English" },
|
||||
{ code: "fr", Flag: FlagFR, label: "Français" },
|
||||
];
|
||||
|
||||
// Plain module-level function, not part of the component body — setting a
|
||||
@@ -26,6 +34,7 @@ function setMarketingLocaleCookie(code: Locale) {
|
||||
*/
|
||||
export function LanguageSwitcher({ current }: { current: Locale }) {
|
||||
const router = useRouter();
|
||||
const CurrentFlag = OPTIONS.find((o) => o.code === current)?.Flag ?? Globe;
|
||||
|
||||
function select(code: Locale) {
|
||||
if (code === current) return;
|
||||
@@ -34,22 +43,22 @@ export function LanguageSwitcher({ current }: { current: Locale }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-0.5" role="group" aria-label="Language">
|
||||
{OPTIONS.map(({ code, flag, label }) => (
|
||||
<button
|
||||
key={code}
|
||||
type="button"
|
||||
onClick={() => select(code)}
|
||||
aria-label={label}
|
||||
aria-pressed={current === code}
|
||||
title={label}
|
||||
className={`text-base leading-none p-1.5 rounded-md transition-opacity ${
|
||||
current === code ? "opacity-100" : "opacity-40 hover:opacity-70"
|
||||
}`}
|
||||
>
|
||||
{flag}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
className="p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
|
||||
aria-label="Change language"
|
||||
>
|
||||
<CurrentFlag className="h-4 w-5 rounded-[2px]" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{OPTIONS.map(({ code, Flag, label }) => (
|
||||
<DropdownMenuItem key={code} onClick={() => select(code)} className="gap-2">
|
||||
<Flag className="h-3.5 w-[1.15rem] rounded-[2px] shrink-0" />
|
||||
<span className="flex-1">{label}</span>
|
||||
{current === code && <Check className="h-3.5 w-3.5" />}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user