feat: update product categories data structure and implement sitemap generation
- Refactored product categories to use a new data structure. - Updated API routes to fetch product categories from the new data source. - Implemented sitemap generation script using dotenv for environment variables. - Added sitemap generation endpoint to the API. - Removed old sitemap file and replaced it with a dynamically generated one.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { productCategories } from '../../data';
|
||||
import type { IProductCardProps } from '@/components/pages/products/productCard/productCard.d';
|
||||
import { productCategoriesData } from '../../data';
|
||||
|
||||
// Helper to generate 50 products for a category
|
||||
export function generateProductsForCategory(
|
||||
@@ -18,7 +18,7 @@ export function generateProductsForCategory(
|
||||
// Map of categoryId to products
|
||||
export const productsByCategory: Record<string, IProductCardProps[]> =
|
||||
Object.fromEntries(
|
||||
productCategories.map((cat) => [
|
||||
productCategoriesData.map((cat) => [
|
||||
cat.id,
|
||||
generateProductsForCategory(cat.id, cat.title),
|
||||
]),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextResponse, NextRequest } from 'next/server';
|
||||
import { cookies } from 'next/headers';
|
||||
import { productCategories } from '../../data';
|
||||
import { generateProductsForCategory } from './data';
|
||||
import { productCategories } from '@/app/api/project_categories/data';
|
||||
|
||||
export async function GET(request: NextRequest, context: any) {
|
||||
const cookieStore = await cookies();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { NextResponse, NextRequest } from 'next/server';
|
||||
import { cookies } from 'next/headers';
|
||||
import { productCategories } from '../data';
|
||||
import { productCategoriesData } from '../data';
|
||||
|
||||
interface IContext {
|
||||
params: {
|
||||
@@ -20,7 +20,7 @@ export async function GET(request: NextRequest, context: any) {
|
||||
|
||||
const { id } = params;
|
||||
|
||||
let category = productCategories.find((cat) => cat.id === id);
|
||||
let category = productCategoriesData.find((cat) => cat.id === id);
|
||||
|
||||
if (!category) {
|
||||
return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const productCategories = [
|
||||
export const productCategoriesData = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Ghazaghi',
|
||||
@@ -91,28 +91,4 @@ Facing bricks, also known as face bricks or veneer bricks, are specially designe
|
||||
|
||||
Facing Bricks: Characteristics and Features`,
|
||||
},
|
||||
] as APIProductCategoryEntity[];
|
||||
|
||||
interface APIProductCategoryEntity {
|
||||
id: string;
|
||||
title: string;
|
||||
fa_title?: string;
|
||||
icon: string;
|
||||
typesCount: number;
|
||||
priceTypeTitle: string;
|
||||
fa_priceTypeTitle?: string;
|
||||
bestForTitle: string;
|
||||
fa_bestForTitle?: string;
|
||||
fa_description?: `Facing Bricks: Characteristics and Features
|
||||
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
|
||||
Facing Bricks: Characteristics and Features
|
||||
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
|
||||
|
||||
Facing Bricks: Characteristics and Features`;
|
||||
description?: `Facing Bricks: Characteristics and Features
|
||||
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
|
||||
Facing Bricks: Characteristics and Features
|
||||
Facing bricks, also known as face bricks or veneer bricks, are specially designed for visible areas of a building, primarily the exterior facades, but also for interior walls where aesthetics are important. Unlike common bricks which are often covered by plaster or other materials, facing bricks are chosen for their visual appeal and ability to withstand environmental conditions.
|
||||
|
||||
Facing Bricks: Characteristics and Features`;
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { cookies } from 'next/headers';
|
||||
import { productCategories } from './data';
|
||||
import { APIProductCategoryEntity } from '@/models/api';
|
||||
import { productCategoriesData } from './data';
|
||||
|
||||
export async function GET(request: Request) {
|
||||
let data = productCategories;
|
||||
let data = productCategoriesData as APIProductCategoryEntity[];
|
||||
|
||||
const cookieStore = await cookies();
|
||||
const lang = (await cookieStore).get('lang')?.value || 'fa';
|
||||
|
||||
if (lang === 'fa') {
|
||||
data = productCategories.map(
|
||||
data = productCategoriesData.map(
|
||||
({
|
||||
id,
|
||||
title,
|
||||
@@ -47,5 +48,5 @@ export async function GET(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ data: productCategories });
|
||||
return NextResponse.json({ data });
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
'use server';
|
||||
|
||||
// app/(api)/sitemap/route.ts
|
||||
import { NextResponse } from 'next/server';
|
||||
import { productCategoriesData } from '../product_categories/data';
|
||||
|
||||
const HOST = 'http://localhost:3000';
|
||||
|
||||
const pages = [
|
||||
'/',
|
||||
'/about-us',
|
||||
'/contact-us',
|
||||
'/blog',
|
||||
'/product-categories',
|
||||
'/projects',
|
||||
];
|
||||
|
||||
const locales = ['en', 'fa'];
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
pages.push(
|
||||
...productCategoriesData.map(
|
||||
(productCategory) => `/product-categories/${productCategory.id}`,
|
||||
),
|
||||
);
|
||||
|
||||
const urls = pages.flatMap((page) =>
|
||||
locales.map((locale) => {
|
||||
const loc = `/${locale}`;
|
||||
return `
|
||||
<url>
|
||||
<loc>${HOST}${loc}${page}</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
`;
|
||||
}),
|
||||
);
|
||||
|
||||
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
${urls.join('\n')}
|
||||
</urlset>`;
|
||||
|
||||
return new NextResponse(xml, {
|
||||
headers: {
|
||||
'Content-Type': 'application/xml',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Sitemap generation failed:', err);
|
||||
return new NextResponse('Internal Server Errorsssssss', { status: 500 });
|
||||
}
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
export interface APIProductCategoryEntity {
|
||||
id: string;
|
||||
title: string;
|
||||
fa_title?: string;
|
||||
icon: string;
|
||||
typesCount: number;
|
||||
priceTypeTitle: string;
|
||||
fa_priceTypeTitle?: string;
|
||||
bestForTitle: string;
|
||||
fa_bestForTitle?: string;
|
||||
fa_description?: string;
|
||||
description?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user