feat: Add Docker support and improve API structure
- Introduced Dockerfile and .dockerignore for containerization. - Removed unused API route `src/app/api/hello/route.ts`. - Added new API route for fetching products by category. - Enhanced existing product category API to include descriptions. - Updated product categories data structure to include descriptions. - Improved product fetching logic in the product categories page. - Refactored breadcrumb component for better navigation. - Added new AchievementIconWhite component for UI consistency. - Updated Navbar to use routeFactory for better maintainability. - Enhanced styling in various components for improved responsiveness. - Removed obsolete language switcher component.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export interface IAachievementTextBoxProps {
|
||||
title: string;
|
||||
reverseColor?: boolean;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,19 @@ import { IAachievementTextBoxProps } from './achievementTextBox';
|
||||
|
||||
export default function AchievementTextBox({
|
||||
title,
|
||||
reverseColor,
|
||||
}: IAachievementTextBoxProps) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<Icon name="achievement" className="text-primary" />
|
||||
<span className="text-base text-gray-500">{title}</span>
|
||||
<Icon
|
||||
name={reverseColor ? 'achievementWhite' : 'achievement'}
|
||||
className={`${reverseColor ? 'text-white' : 'text-primary'}`}
|
||||
/>
|
||||
<span
|
||||
className={`text-base ${reverseColor ? 'text-white' : 'text-gray-500'}`}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface IBreadcrumbProps {
|
||||
items: IBreadcrumbItem[];
|
||||
}
|
||||
|
||||
export interface IBreadcrumbItem {
|
||||
title: string;
|
||||
href?: string;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import Link from 'next/link';
|
||||
import { IBreadcrumbProps } from './breadcrumb';
|
||||
|
||||
export default function Breadcrumb({ items }: IBreadcrumbProps) {
|
||||
return (
|
||||
<nav aria-label="breadcrumb">
|
||||
<div className="flex items-center gap-2">
|
||||
{items.map((item, index) => (
|
||||
<div key={index} className="flex items-center gap-2">
|
||||
{index > 0 && (
|
||||
<span className="text-sm font-normal text-gray-300">⦁</span>
|
||||
)}
|
||||
{item.href ? (
|
||||
<Link
|
||||
href={item.href}
|
||||
className="text-base font-normal text-gray-300"
|
||||
>
|
||||
{item.title}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-primary text-base font-bold">
|
||||
{item.title}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
'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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -94,18 +94,19 @@ import { usePathname } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import HamburgerMenu from '../hamburgerMenu';
|
||||
import { t } from '@/locales/translates';
|
||||
import routeFactory from '@/assets/constants/routeFactory';
|
||||
|
||||
export default function Navbar() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const pathname = usePathname();
|
||||
|
||||
const links = [
|
||||
{ href: '/', label: t('pages_home_title') as string },
|
||||
{ href: '/about', label: t('pages_about_title') as string },
|
||||
{ href: '/blog', label: t('pages_blog_title') as string },
|
||||
{ href: '/contact', label: t('pages_contact_title') as string },
|
||||
{ href: '/product', label: t('pages_product_categories_title') as string },
|
||||
{ href: '/project', label: t('pages_projects_title') as string },
|
||||
routeFactory.home,
|
||||
routeFactory.productCategories,
|
||||
routeFactory.projects,
|
||||
routeFactory.blog,
|
||||
routeFactory.about,
|
||||
routeFactory.contact,
|
||||
];
|
||||
const linkClass = (href: string) =>
|
||||
pathname === href ? 'text-primary font-semibold' : 'text-white';
|
||||
@@ -123,13 +124,13 @@ export default function Navbar() {
|
||||
</Link>
|
||||
|
||||
<ul className="hidden space-x-6 text-sm md:flex lg:text-base">
|
||||
{links.map(({ href, label }) => (
|
||||
<li key={href}>
|
||||
{links.map(({ route, title }) => (
|
||||
<li key={route()}>
|
||||
<Link
|
||||
href={href}
|
||||
className={`${linkClass(href)} hover:text-primary-light`}
|
||||
href={route()}
|
||||
className={`${linkClass(route())} hover:text-primary-light`}
|
||||
>
|
||||
{label}
|
||||
{title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user