feat(i18n): localize global app shell announcement bar and widgets

This commit is contained in:
Poyraz
2026-06-27 15:32:18 +03:00
parent d0d3c17ba6
commit 79b37e209a
6 changed files with 49 additions and 16 deletions
+10 -4
View File
@@ -2,11 +2,13 @@
import { Icon } from "@iconify/react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { usePathname } from "@/i18n/routing";
import { AnnouncementBar } from "poyraz-ui/organisms";
import { SiteNavbar } from "@/components/site-navbar";
import { NekoFollower } from "@/components/neko-follower";
import { ANNOUNCEMENT_ITEMS, ENABLE_NEKO_FOLLOWER } from "@/data/site-settings";
import { useLocale } from "next-intl";
import { getLocalizedValue } from "@/lib/locale";
import dynamic from "next/dynamic";
const AtaturkWidgetModal = dynamic(
@@ -20,6 +22,7 @@ type AppShellProps = {
export function AppShell({ children }: AppShellProps) {
const pathname = usePathname();
const locale = useLocale();
const announcement = ANNOUNCEMENT_ITEMS[0];
const isStandaloneLinksPage =
pathname === "/links" || pathname.startsWith("/links/");
@@ -28,6 +31,9 @@ export function AppShell({ children }: AppShellProps) {
return children;
}
const localizedText = announcement ? getLocalizedValue(announcement.text, locale) : "";
const localizedActionLabel = announcement ? getLocalizedValue(announcement.actionLabel, locale) : "";
return (
<>
<AtaturkWidgetModal />
@@ -40,19 +46,19 @@ export function AppShell({ children }: AppShellProps) {
dismissible={false}
icon={<Icon icon="mdi:sparkles" width={16} height={16} />}
action={
announcement.actionLabel && announcement.actionHref ? (
localizedActionLabel && announcement.actionHref ? (
<Link
href={announcement.actionHref}
target="_blank"
rel="noreferrer"
className="text-xs font-bold underline"
>
{announcement.actionLabel}
{localizedActionLabel}
</Link>
) : null
}
>
{announcement.text}
{localizedText}
</AnnouncementBar>
) : null}
<main className="flex-1 py-4">{children}</main>
+10 -6
View File
@@ -5,22 +5,26 @@ import Script from "next/script";
import Image from "next/image";
import { Modal, ModalContent, ModalTrigger, ModalTitle } from "poyraz-ui/molecules";
import { Skeleton } from "poyraz-ui/atoms";
import { useLocale, useTranslations } from "next-intl";
export function AtaturkWidgetModal() {
const [isLoading, setIsLoading] = useState(true);
const t = useTranslations("AtaturkWidget");
const locale = useLocale();
return (
<Modal>
<ModalTrigger asChild>
<button
type="button"
title="Bugünün Atatürk Sözü"
title={t("title")}
className="fixed bottom-4 left-4 z-50 flex h-14 w-14 items-center justify-center overflow-hidden rounded-full border-2 border-red-600 bg-background shadow-lg transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
aria-label="Bugünün Atatürk Sözü"
aria-label={t("title")}
>
<div className="relative h-full w-full">
<Image
src="/ataturk.png"
alt="Mustafa Kemal Atatürk"
alt={t("alt")}
fill
sizes="56px"
className="object-cover"
@@ -30,7 +34,7 @@ export function AtaturkWidgetModal() {
</ModalTrigger>
<ModalContent className="flex flex-col justify-center p-6 sm:max-w-[425px] min-h-[160px] transition-all duration-300">
<ModalTitle className="sr-only">Bugünün Atatürk Sözü</ModalTitle>
<ModalTitle className="sr-only">{t("title")}</ModalTitle>
{isLoading && (
<div className="flex w-full flex-col space-y-3">
@@ -44,11 +48,11 @@ export function AtaturkWidgetModal() {
)}
<div className={`w-full ${isLoading ? "hidden" : "block"}`}>
<div data-ataturk-quote-widget data-language="tr" data-theme="light"></div>
<div data-ataturk-quote-widget data-language={locale} data-theme="light"></div>
<Script
src="https://ataturk-kronolojisi.org/widget/quote.js"
strategy="lazyOnload"
data-language="tr"
data-language={locale}
data-theme="light"
onReady={() => setIsLoading(false)}
/>
+4 -1
View File
@@ -1,8 +1,11 @@
import { Card } from "poyraz-ui/atoms";
import { YOUTUBE_VIDEO_LINKS } from "@/data/youtube-videos";
import { YoutubeLiteEmbed } from "@/components/youtube-lite-embed";
import { useTranslations } from "next-intl";
export function HomeVideosSection() {
const t = useTranslations("Content");
return (
<section className="space-y-2">
<div className="grid gap-2 md:grid-cols-3">
@@ -11,7 +14,7 @@ export function HomeVideosSection() {
key={link}
className="overflow-hidden rounded-sm border-border p-0"
>
<YoutubeLiteEmbed link={link} title="YouTube video oynatici" />
<YoutubeLiteEmbed link={link} title={t("youtubeEmbedTitle")} />
</Card>
))}
</div>