This commit is contained in:
2026-05-25 09:12:22 +03:30
parent 19e53d4b97
commit aae6a4b49b
13 changed files with 4770 additions and 48 deletions
+5
View File
@@ -2,3 +2,8 @@
node_modules
npm-debug.log
.next/cache
.next
.git
.gitignore
README.md
*.log
+2
View File
@@ -42,3 +42,5 @@ next-env.d.ts
contactMessages.json
public/sitemap.xml
data/
+22 -19
View File
@@ -1,28 +1,31 @@
# Build stage
FROM node:20-alpine AS builder
FROM node:20-alpine AS base
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install
ENV NEXT_TELEMETRY_DISABLED=1
FROM base AS deps
COPY package.json pnpm-lock.yml ./
RUN npm i -g pnpm
RUN pnpm install --frozen-lockfile
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build
ENV PORT=5000
ENV VERCEL_PROJECT_PRODUCTION_URL=http://194.59.214.243:5000
ENV NEXT_PUBLIC_API_BASE_URL=http://194.59.214.243:5000/api
RUN yarn run build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=5000
ENV VERCEL_PROJECT_PRODUCTION_URL=http://194.59.214.243:5000
ENV NEXT_PUBLIC_API_BASE_URL=http://194.59.214.243:5000/api
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/node_modules ./node_modules
VOLUME ["/app/contactMessages.json"]
RUN addgroup -S nodejs && adduser -S nextjs -G nodejs
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
RUN touch /app/contactMessages.json && chown nextjs:nodejs /app/contactMessages.json
USER nextjs
EXPOSE 5000
CMD ["yarn", "start"]
CMD ["node", "server.js"]
+17
View File
@@ -0,0 +1,17 @@
services:
web:
build:
context: .
dockerfile: Dockerfile
image: pasargad-bricks:latest
container_name: pasargad-bricks
restart: unless-stopped
ports:
- "5000:5000"
environment:
NODE_ENV: production
PORT: 5000
env_file:
- .env
volumes:
- ./data/contactMessages.json:/app/data/contactMessages.json
+3 -1
View File
@@ -7,6 +7,8 @@ const withNextIntl = createNextIntlPlugin({
},
});
const config: NextConfig = {};
const config: NextConfig = {
output: 'standalone',
};
export default withNextIntl(config);
+4682
View File
File diff suppressed because it is too large Load Diff
+16 -4
View File
@@ -7,6 +7,7 @@ import InnerPageBanner from '@/components/layout/innerPages/banner';
import { IPageParams } from '@/models/layout';
import { getPost } from '@/services/blog';
import { getTranslations } from 'next-intl/server';
import { notFound } from 'next/navigation';
interface IParams {
id: string;
@@ -20,7 +21,14 @@ export async function generateMetadata({
const paramsData = await params;
const { id: postId, locale } = paramsData;
const t = await getTranslations({ locale });
const postData = await getPost(postId);
const postData = await getPost(postId).catch(() => null);
if (!postData) {
return {
title: t('page_blog'),
description: t('page_blog_metadata_description'),
};
}
return {
title: postData.title,
@@ -35,11 +43,15 @@ export default async function PostPage({
}) {
const paramsData = await params;
const t = await getTranslations({ locale: paramsData.locale });
const { id: postId, locale } = await params;
const { id: postId, locale } = paramsData;
const routes = routeFactory(t, locale);
const postData = await getPost(postId);
const postData = await getPost(postId).catch((error) => {
if (error?.response?.status === 404) {
notFound();
}
throw error;
});
const breadcrumbItems = [
{
-3
View File
@@ -53,10 +53,7 @@ export default async function RootLayout({
return (
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
<Head>
<meta name="robots" content="index, follow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:site_name" content="کارخانه آجرپزی پاسارگاد" />
<meta name="author" content="پاسارگاد" />
{/* <link rel="icon" href="/favicon.ico" /> */}
<link
rel="icon"
+15 -15
View File
@@ -27,21 +27,21 @@ export const posts: IPostData[] = [
content: [
{
type: 'title',
data: 'روش‌های پایدار برای کاهش ضایعات در تولید صنعتی',
data: 'Sustainable practices to reduce waste in industrial production',
},
{
type: 'content',
data: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.',
data: 'Sustainable manufacturing focuses on minimizing waste, optimizing resource use, and improving process efficiency. By adopting circular design, material recovery, and energy-efficient processes, manufacturers can reduce environmental impact while maintaining productivity and cost-effectiveness.',
},
{
type: 'bullet',
data: [
'روش‌های پایدار برای کاهش ضایعات در تولید صنعتی',
'رباتیک پیشرفته و تحول فرآیندهای صنعتی',
'مزایای اصلی استفاده از رباتیک در تولید',
'استفاده از تحلیل داده برای تولید هوشمندتر',
'کاهش هزینه‌ها با اتوماسیون',
'مزایای راه‌حل‌های سفارشی‌سازی در تولید',
'Sustainable practices to reduce waste in industrial production',
'Advanced robotics transforming industrial processes',
'Key benefits of using robotics in manufacturing',
'Using data analytics for smarter production',
'Reducing costs through automation',
'Advantages of customized manufacturing solutions',
],
},
{
@@ -50,18 +50,18 @@ export const posts: IPostData[] = [
src: '/images/project2.jpeg',
alt: '',
thumbTitle:
'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.',
'Sample image illustrating sustainable manufacturing practices.',
},
},
{
type: 'numberList',
data: [
'روش‌های پایدار برای کاهش ضایعات در تولید صنعتی',
'رباتیک پیشرفته و تحول فرآیندهای صنعتی',
'مزایای اصلی استفاده از رباتیک در تولید',
'استفاده از تحلیل داده برای تولید هوشمندتر',
'کاهش هزینه‌ها با اتوماسیون',
'مزایای راه‌حل‌های سفارشی‌سازی در تولید',
'Sustainable practices to reduce waste in industrial production',
'Advanced robotics transforming industrial processes',
'Key benefits of using robotics in manufacturing',
'Using data analytics for smarter production',
'Reducing costs through automation',
'Advantages of customized manufacturing solutions',
],
},
],
+4 -2
View File
@@ -1,11 +1,13 @@
import { NextRequest, NextResponse } from 'next/server';
import { writeFile, readFile } from 'fs/promises';
import { mkdir, writeFile, readFile } from 'fs/promises';
import path from 'path';
const filePath = path.resolve(process.cwd(), 'contactMessages.json');
const filePath = path.resolve(process.cwd(), 'data', 'contactMessages.json');
export async function POST(request: NextRequest) {
try {
await mkdir(path.dirname(filePath), { recursive: true });
const body = await request.json();
const { first_name, last_name, phone, email, message } = body;
+2 -2
View File
@@ -1,7 +1,7 @@
'use server';
import { NextResponse, NextRequest } from 'next/server';
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { productCategoriesData } from '../data';
export async function GET(request: NextRequest, context: any) {
@@ -10,7 +10,7 @@ export async function GET(request: NextRequest, context: any) {
const params = (await context).params;
const { id } = params;
const { id } = await params;
let category = productCategoriesData.find((cat) => cat.id === id);
+1 -1
View File
@@ -4,7 +4,7 @@ import Button from '@/components/uikit/button';
import { TLocales } from '@/models/layout';
import Image from 'next/image';
import Link from 'next/link';
import { useTranslations } from 'use-intl';
import { useTranslations } from 'next-intl';
interface Props {
post: IPostThumbResponseData;
@@ -50,7 +50,7 @@ import 'swiper/css/free-mode';
import PostThumb from './PostThumb';
import { IPostThumbResponseData } from '@/app/api/blog/data';
import { TLocales } from '@/models/layout';
import { useTranslations } from 'use-intl';
import { useTranslations } from 'next-intl';
import routeFactory from '@/assets/constants/routeFactory';
import SliderThumbSkeleton from '@/components/layout/sliderSkeleton';