Merge remote-tracking branch 'origin' into navbar
This commit is contained in:
+2
-4
@@ -1,7 +1,5 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from 'next';
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {};
|
||||||
/* config options here */
|
|
||||||
};
|
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
Generated
+2
-14
@@ -8,13 +8,9 @@
|
|||||||
"name": "pasargad_bricks",
|
"name": "pasargad_bricks",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"i18next": "^25.2.1",
|
|
||||||
"i18next-browser-languagedetector": "^8.1.0",
|
|
||||||
"i18next-http-backend": "^3.0.2",
|
|
||||||
"next": "15.3.3",
|
"next": "15.3.3",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0"
|
||||||
"react-i18next": "^15.5.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
@@ -57,14 +53,6 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
|
||||||
"version": "7.27.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.4.tgz",
|
|
||||||
"integrity": "sha512-t3yaEOuGu9NlIZ+hIeGbBjFtZT7j2cb2tg0fuaJKeGotchRjjLfrBA9Kwf8quhpP1EUuxModQg04q/mBwyg8uA==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/core": {
|
"node_modules/@emnapi/core": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz",
|
||||||
@@ -5762,7 +5750,7 @@
|
|||||||
"version": "5.8.3",
|
"version": "5.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|||||||
+1
-5
@@ -9,13 +9,9 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"i18next": "^25.2.1",
|
|
||||||
"i18next-browser-languagedetector": "^8.1.0",
|
|
||||||
"i18next-http-backend": "^3.0.2",
|
|
||||||
"next": "15.3.3",
|
"next": "15.3.3",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0"
|
||||||
"react-i18next": "^15.5.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3",
|
"@eslint/eslintrc": "^3",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default async function Home() {
|
|||||||
const data = await getData();
|
const data = await getData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-between p-24 text-gray-300">
|
<main className="flex min-h-screen flex-col items-center justify-between p-24 text-bg-primary">
|
||||||
ssss
|
ssss
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|||||||
+8
-8
@@ -1,24 +1,24 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
import { I18nextProvider } from 'react-i18next';
|
import { cookies } from 'next/headers';
|
||||||
import i18n from '../config/i18n';
|
|
||||||
|
|
||||||
// export const metadata: Metadata = {
|
// export const metadata: Metadata = {
|
||||||
// title: 'Create Next App',
|
// title: 'Create Next App',
|
||||||
// description: 'Generated by create next app',
|
// description: 'Generated by create next app',
|
||||||
// };
|
// };
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}>) {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const locale = cookieStore.get('lang')?.value || 'en';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
|
||||||
<I18nextProvider i18n={i18n}>
|
|
||||||
<body>{children}</body>
|
<body>{children}</body>
|
||||||
</I18nextProvider>
|
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -1,6 +1,8 @@
|
|||||||
// ... existing imports ...
|
// ... existing imports ...
|
||||||
import Header from '@/components/layout/header';
|
import Header from '@/components/layout/header';
|
||||||
import Navbar from '@/components/layout/navbar';
|
import Navbar from '@/components/layout/navbar';
|
||||||
|
import ChangeLangButton from '@/components/layout/languageSwitcher';
|
||||||
|
import { changeLanguage, t } from '@/locales/translates';
|
||||||
|
|
||||||
async function getData() {
|
async function getData() {
|
||||||
// Simulate a delay to show server-side data fetching
|
// Simulate a delay to show server-side data fetching
|
||||||
@@ -8,13 +10,18 @@ async function getData() {
|
|||||||
return { message: 'This data was fetched on the server!' };
|
return { message: 'This data was fetched on the server!' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const change = () => {
|
||||||
|
changeLanguage('fa');
|
||||||
|
};
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
const data = await getData();
|
const data = await getData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="">
|
<main className="flex min-h-screen flex-col items-center justify-between p-24 text-gray-300">
|
||||||
<Header/>
|
<Header/>
|
||||||
{/* <Navbar/> */}
|
<span>{t('pages_home_title') as string}</span>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { t, translates } from '@/locales/translates';
|
||||||
const { t } = useTranslation('routes');
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
home: {
|
home: {
|
||||||
title: t('home'),
|
title: t('pages_home_title'),
|
||||||
route: () => '/',
|
route: () => '/',
|
||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
title: t('about'),
|
title: t('pages_about_title'),
|
||||||
route: () => '/about',
|
route: () => '/about',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
'use client';
|
||||||
|
import { changeLanguage, TLocales } from '@/locales/translates';
|
||||||
|
import Button from '../Button';
|
||||||
|
|
||||||
|
export default function ChangeLangButton() {
|
||||||
|
const changeLang = (lang: TLocales) => {
|
||||||
|
changeLanguage(lang);
|
||||||
|
window.location.reload(); // Reload to get new SSR content
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button onClick={() => changeLang('en')}>English</Button>
|
||||||
|
<Button onClick={() => changeLang('fa')}>فارسی</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
'use client';
|
||||||
import React, { ButtonHTMLAttributes, ReactNode } from 'react';
|
import React, { ButtonHTMLAttributes, ReactNode } from 'react';
|
||||||
|
|
||||||
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import i18n from 'i18next';
|
|
||||||
import { initReactI18next } from 'react-i18next';
|
|
||||||
import Backend from 'i18next-http-backend';
|
|
||||||
|
|
||||||
i18n
|
|
||||||
.use(Backend)
|
|
||||||
.use(initReactI18next)
|
|
||||||
.init({
|
|
||||||
fallbackLng: 'en',
|
|
||||||
debug: false,
|
|
||||||
interpolation: {
|
|
||||||
escapeValue: false,
|
|
||||||
},
|
|
||||||
backend: {
|
|
||||||
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default i18n;
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
const en = {
|
||||||
|
pages_home_title: 'Home',
|
||||||
|
pages_home_description: 'Welcome to the home page',
|
||||||
|
pages_about_title: 'About Us',
|
||||||
|
pages_about_description: 'Learn more about us on this page',
|
||||||
|
pages_contact_title: 'Contact Us',
|
||||||
|
pages_contact_description: 'Get in touch with us through this page',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default en;
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Translates } from './translates';
|
||||||
|
|
||||||
|
const fa = {
|
||||||
|
pages_home_title: 'صفحهی اصلی',
|
||||||
|
pages_home_description: 'Welcome to the home page',
|
||||||
|
pages_about_title: 'About Us',
|
||||||
|
pages_about_description: 'Learn more about us on this page',
|
||||||
|
pages_contact_title: 'Contact Us',
|
||||||
|
pages_contact_description: 'Get in touch with us through this page',
|
||||||
|
} as Translates;
|
||||||
|
|
||||||
|
export default fa;
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import en from './en';
|
||||||
|
import fa from './fa';
|
||||||
|
|
||||||
|
// Universal getCookie function
|
||||||
|
export function getCookie(name: string): string | undefined {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
// Client-side
|
||||||
|
const match = document.cookie.match(
|
||||||
|
new RegExp('(^| )' + name + '=([^;]+)'),
|
||||||
|
);
|
||||||
|
return match ? decodeURIComponent(match[2]) : undefined;
|
||||||
|
} else {
|
||||||
|
// Server-side (Next.js App Router)
|
||||||
|
try {
|
||||||
|
// Dynamically import to avoid errors in client bundle
|
||||||
|
const { cookies } = require('next/headers');
|
||||||
|
return cookies().get(name)?.value;
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Universal setCookie function to change language
|
||||||
|
export function changeLanguage(lang: TLocales, days = 365) {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
// Client-side
|
||||||
|
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
||||||
|
document.cookie = `lang=${encodeURIComponent(lang)}; expires=${expires}; path=/`;
|
||||||
|
} else {
|
||||||
|
// Server-side (Next.js App Router)
|
||||||
|
try {
|
||||||
|
const { cookies } = require('next/headers');
|
||||||
|
cookies().set('lang', lang, { path: '/', maxAge: days * 24 * 60 * 60 });
|
||||||
|
} catch {
|
||||||
|
// No-op on server if not available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const locales = {
|
||||||
|
en: en as Translates,
|
||||||
|
fa,
|
||||||
|
} as Record<TLocales, Translates>;
|
||||||
|
|
||||||
|
export const translates = (key: keyof Translates): string | (() => string) => {
|
||||||
|
const lang = (getCookie('lang') || 'en') as TLocales;
|
||||||
|
return locales[lang][key] || locales.en[key] || key;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const t = (key: keyof Translates) => translates(key);
|
||||||
|
|
||||||
|
export type TLocales = 'en' | 'fa';
|
||||||
|
|
||||||
|
export type Translates = {
|
||||||
|
[K in keyof typeof en]: string | (() => string);
|
||||||
|
};
|
||||||
+1
-1
@@ -9,7 +9,6 @@ const config: Config = {
|
|||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
// Move your custom colors directly here to override default Tailwind colors
|
// Move your custom colors directly here to override default Tailwind colors
|
||||||
extend: {
|
|
||||||
colors: {
|
colors: {
|
||||||
// Custom colors
|
// Custom colors
|
||||||
primary: {
|
primary: {
|
||||||
@@ -54,6 +53,7 @@ const config: Config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
extend: {
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
||||||
'gradient-conic':
|
'gradient-conic':
|
||||||
|
|||||||
Reference in New Issue
Block a user