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:
2025-06-05 16:03:59 +03:30
parent d44aa203e0
commit 0bd5060580
28 changed files with 403 additions and 111 deletions
@@ -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>
);
}
+8
View File
@@ -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>
</>
);
}
+12 -11
View File
@@ -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>
))}