feat(i18n): localize global app shell announcement bar and widgets
This commit is contained in:
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "@/i18n/routing";
|
||||||
import { AnnouncementBar } from "poyraz-ui/organisms";
|
import { AnnouncementBar } from "poyraz-ui/organisms";
|
||||||
import { SiteNavbar } from "@/components/site-navbar";
|
import { SiteNavbar } from "@/components/site-navbar";
|
||||||
import { NekoFollower } from "@/components/neko-follower";
|
import { NekoFollower } from "@/components/neko-follower";
|
||||||
import { ANNOUNCEMENT_ITEMS, ENABLE_NEKO_FOLLOWER } from "@/data/site-settings";
|
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";
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
const AtaturkWidgetModal = dynamic(
|
const AtaturkWidgetModal = dynamic(
|
||||||
@@ -20,6 +22,7 @@ type AppShellProps = {
|
|||||||
|
|
||||||
export function AppShell({ children }: AppShellProps) {
|
export function AppShell({ children }: AppShellProps) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
const locale = useLocale();
|
||||||
const announcement = ANNOUNCEMENT_ITEMS[0];
|
const announcement = ANNOUNCEMENT_ITEMS[0];
|
||||||
const isStandaloneLinksPage =
|
const isStandaloneLinksPage =
|
||||||
pathname === "/links" || pathname.startsWith("/links/");
|
pathname === "/links" || pathname.startsWith("/links/");
|
||||||
@@ -28,6 +31,9 @@ export function AppShell({ children }: AppShellProps) {
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const localizedText = announcement ? getLocalizedValue(announcement.text, locale) : "";
|
||||||
|
const localizedActionLabel = announcement ? getLocalizedValue(announcement.actionLabel, locale) : "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AtaturkWidgetModal />
|
<AtaturkWidgetModal />
|
||||||
@@ -40,19 +46,19 @@ export function AppShell({ children }: AppShellProps) {
|
|||||||
dismissible={false}
|
dismissible={false}
|
||||||
icon={<Icon icon="mdi:sparkles" width={16} height={16} />}
|
icon={<Icon icon="mdi:sparkles" width={16} height={16} />}
|
||||||
action={
|
action={
|
||||||
announcement.actionLabel && announcement.actionHref ? (
|
localizedActionLabel && announcement.actionHref ? (
|
||||||
<Link
|
<Link
|
||||||
href={announcement.actionHref}
|
href={announcement.actionHref}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="text-xs font-bold underline"
|
className="text-xs font-bold underline"
|
||||||
>
|
>
|
||||||
{announcement.actionLabel}
|
{localizedActionLabel}
|
||||||
</Link>
|
</Link>
|
||||||
) : null
|
) : null
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{announcement.text}
|
{localizedText}
|
||||||
</AnnouncementBar>
|
</AnnouncementBar>
|
||||||
) : null}
|
) : null}
|
||||||
<main className="flex-1 py-4">{children}</main>
|
<main className="flex-1 py-4">{children}</main>
|
||||||
|
|||||||
@@ -5,22 +5,26 @@ import Script from "next/script";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Modal, ModalContent, ModalTrigger, ModalTitle } from "poyraz-ui/molecules";
|
import { Modal, ModalContent, ModalTrigger, ModalTitle } from "poyraz-ui/molecules";
|
||||||
import { Skeleton } from "poyraz-ui/atoms";
|
import { Skeleton } from "poyraz-ui/atoms";
|
||||||
|
import { useLocale, useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function AtaturkWidgetModal() {
|
export function AtaturkWidgetModal() {
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const t = useTranslations("AtaturkWidget");
|
||||||
|
const locale = useLocale();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal>
|
<Modal>
|
||||||
<ModalTrigger asChild>
|
<ModalTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="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"
|
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">
|
<div className="relative h-full w-full">
|
||||||
<Image
|
<Image
|
||||||
src="/ataturk.png"
|
src="/ataturk.png"
|
||||||
alt="Mustafa Kemal Atatürk"
|
alt={t("alt")}
|
||||||
fill
|
fill
|
||||||
sizes="56px"
|
sizes="56px"
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
@@ -30,7 +34,7 @@ export function AtaturkWidgetModal() {
|
|||||||
</ModalTrigger>
|
</ModalTrigger>
|
||||||
|
|
||||||
<ModalContent className="flex flex-col justify-center p-6 sm:max-w-[425px] min-h-[160px] transition-all duration-300">
|
<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 && (
|
{isLoading && (
|
||||||
<div className="flex w-full flex-col space-y-3">
|
<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 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
|
<Script
|
||||||
src="https://ataturk-kronolojisi.org/widget/quote.js"
|
src="https://ataturk-kronolojisi.org/widget/quote.js"
|
||||||
strategy="lazyOnload"
|
strategy="lazyOnload"
|
||||||
data-language="tr"
|
data-language={locale}
|
||||||
data-theme="light"
|
data-theme="light"
|
||||||
onReady={() => setIsLoading(false)}
|
onReady={() => setIsLoading(false)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { Card } from "poyraz-ui/atoms";
|
import { Card } from "poyraz-ui/atoms";
|
||||||
import { YOUTUBE_VIDEO_LINKS } from "@/data/youtube-videos";
|
import { YOUTUBE_VIDEO_LINKS } from "@/data/youtube-videos";
|
||||||
import { YoutubeLiteEmbed } from "@/components/youtube-lite-embed";
|
import { YoutubeLiteEmbed } from "@/components/youtube-lite-embed";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export function HomeVideosSection() {
|
export function HomeVideosSection() {
|
||||||
|
const t = useTranslations("Content");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<div className="grid gap-2 md:grid-cols-3">
|
<div className="grid gap-2 md:grid-cols-3">
|
||||||
@@ -11,7 +14,7 @@ export function HomeVideosSection() {
|
|||||||
key={link}
|
key={link}
|
||||||
className="overflow-hidden rounded-sm border-border p-0"
|
className="overflow-hidden rounded-sm border-border p-0"
|
||||||
>
|
>
|
||||||
<YoutubeLiteEmbed link={link} title="YouTube video oynatici" />
|
<YoutubeLiteEmbed link={link} title={t("youtubeEmbedTitle")} />
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+17
-5
@@ -1,7 +1,13 @@
|
|||||||
export type AnnouncementItem = {
|
export type AnnouncementItem = {
|
||||||
id: string;
|
id: string;
|
||||||
text: string;
|
text: {
|
||||||
actionLabel: string;
|
tr: string;
|
||||||
|
en: string;
|
||||||
|
};
|
||||||
|
actionLabel: {
|
||||||
|
tr: string;
|
||||||
|
en: string;
|
||||||
|
};
|
||||||
actionHref: string;
|
actionHref: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10,8 +16,14 @@ export const ENABLE_NEKO_FOLLOWER = true;
|
|||||||
export const ANNOUNCEMENT_ITEMS: AnnouncementItem[] = [
|
export const ANNOUNCEMENT_ITEMS: AnnouncementItem[] = [
|
||||||
{
|
{
|
||||||
id: "main-announcement",
|
id: "main-announcement",
|
||||||
text: 'Yeni Projem "Neta" Yayında!',
|
text: {
|
||||||
actionLabel: "İncele ->",
|
tr: 'Yeni Projem "Neta" Yayında!',
|
||||||
|
en: 'My New Project "Neta" is Live!',
|
||||||
|
},
|
||||||
|
actionLabel: {
|
||||||
|
tr: "İncele ->",
|
||||||
|
en: "Explore ->",
|
||||||
|
},
|
||||||
actionHref: "https://www.takeneta.com",
|
actionHref: "https://www.takeneta.com",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -111,5 +111,9 @@
|
|||||||
"email": "Email",
|
"email": "Email",
|
||||||
"linkedin": "LinkedIn",
|
"linkedin": "LinkedIn",
|
||||||
"instagram": "Instagram"
|
"instagram": "Instagram"
|
||||||
|
},
|
||||||
|
"AtaturkWidget": {
|
||||||
|
"title": "Atatürk's Quote of the Day",
|
||||||
|
"alt": "Mustafa Kemal Atatürk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,5 +111,9 @@
|
|||||||
"email": "E-posta",
|
"email": "E-posta",
|
||||||
"linkedin": "LinkedIn",
|
"linkedin": "LinkedIn",
|
||||||
"instagram": "Instagram"
|
"instagram": "Instagram"
|
||||||
|
},
|
||||||
|
"AtaturkWidget": {
|
||||||
|
"title": "Bugünün Atatürk Sözü",
|
||||||
|
"alt": "Mustafa Kemal Atatürk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user