update
This commit is contained in:
@@ -2,3 +2,8 @@
|
|||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
.next/cache
|
.next/cache
|
||||||
|
.next
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
|
*.log
|
||||||
|
|||||||
@@ -42,3 +42,5 @@ next-env.d.ts
|
|||||||
|
|
||||||
contactMessages.json
|
contactMessages.json
|
||||||
public/sitemap.xml
|
public/sitemap.xml
|
||||||
|
|
||||||
|
data/
|
||||||
|
|||||||
+22
-19
@@ -1,28 +1,31 @@
|
|||||||
# Build stage
|
FROM node:20-alpine AS base
|
||||||
FROM node:20-alpine AS builder
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package.json yarn.lock ./
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
RUN yarn install
|
|
||||||
|
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 . .
|
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
|
FROM node:20-alpine AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
ENV PORT=5000
|
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
|
EXPOSE 5000
|
||||||
CMD ["yarn", "start"]
|
CMD ["node", "server.js"]
|
||||||
|
|||||||
@@ -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
@@ -7,6 +7,8 @@ const withNextIntl = createNextIntlPlugin({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const config: NextConfig = {};
|
const config: NextConfig = {
|
||||||
|
output: 'standalone',
|
||||||
|
};
|
||||||
|
|
||||||
export default withNextIntl(config);
|
export default withNextIntl(config);
|
||||||
|
|||||||
Generated
+4682
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ import InnerPageBanner from '@/components/layout/innerPages/banner';
|
|||||||
import { IPageParams } from '@/models/layout';
|
import { IPageParams } from '@/models/layout';
|
||||||
import { getPost } from '@/services/blog';
|
import { getPost } from '@/services/blog';
|
||||||
import { getTranslations } from 'next-intl/server';
|
import { getTranslations } from 'next-intl/server';
|
||||||
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
interface IParams {
|
interface IParams {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -20,7 +21,14 @@ export async function generateMetadata({
|
|||||||
const paramsData = await params;
|
const paramsData = await params;
|
||||||
const { id: postId, locale } = paramsData;
|
const { id: postId, locale } = paramsData;
|
||||||
const t = await getTranslations({ locale });
|
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 {
|
return {
|
||||||
title: postData.title,
|
title: postData.title,
|
||||||
@@ -35,11 +43,15 @@ export default async function PostPage({
|
|||||||
}) {
|
}) {
|
||||||
const paramsData = await params;
|
const paramsData = await params;
|
||||||
const t = await getTranslations({ locale: paramsData.locale });
|
const t = await getTranslations({ locale: paramsData.locale });
|
||||||
|
const { id: postId, locale } = paramsData;
|
||||||
const { id: postId, locale } = await params;
|
|
||||||
const routes = routeFactory(t, locale);
|
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 = [
|
const breadcrumbItems = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,10 +53,7 @@ export default async function RootLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
|
<html lang={locale} dir={locale === 'fa' ? 'rtl' : 'ltr'}>
|
||||||
<Head>
|
<Head>
|
||||||
<meta name="robots" content="index, follow" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<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" href="/favicon.ico" /> */}
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
|
|||||||
+15
-15
@@ -27,21 +27,21 @@ export const posts: IPostData[] = [
|
|||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
type: 'title',
|
type: 'title',
|
||||||
data: 'روشهای پایدار برای کاهش ضایعات در تولید صنعتی',
|
data: 'Sustainable practices to reduce waste in industrial production',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'content',
|
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',
|
type: 'bullet',
|
||||||
data: [
|
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',
|
src: '/images/project2.jpeg',
|
||||||
alt: '',
|
alt: '',
|
||||||
thumbTitle:
|
thumbTitle:
|
||||||
'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.',
|
'Sample image illustrating sustainable manufacturing practices.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'numberList',
|
type: 'numberList',
|
||||||
data: [
|
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',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { NextRequest, NextResponse } from 'next/server';
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
import { writeFile, readFile } from 'fs/promises';
|
import { mkdir, writeFile, readFile } from 'fs/promises';
|
||||||
import path from 'path';
|
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) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
|
await mkdir(path.dirname(filePath), { recursive: true });
|
||||||
|
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const { first_name, last_name, phone, email, message } = body;
|
const { first_name, last_name, phone, email, message } = body;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import { NextResponse, NextRequest } from 'next/server';
|
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
import { productCategoriesData } from '../data';
|
import { productCategoriesData } from '../data';
|
||||||
|
|
||||||
export async function GET(request: NextRequest, context: any) {
|
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 params = (await context).params;
|
||||||
|
|
||||||
const { id } = params;
|
const { id } = await params;
|
||||||
|
|
||||||
let category = productCategoriesData.find((cat) => cat.id === id);
|
let category = productCategoriesData.find((cat) => cat.id === id);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Button from '@/components/uikit/button';
|
|||||||
import { TLocales } from '@/models/layout';
|
import { TLocales } from '@/models/layout';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useTranslations } from 'use-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: IPostThumbResponseData;
|
post: IPostThumbResponseData;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import 'swiper/css/free-mode';
|
|||||||
import PostThumb from './PostThumb';
|
import PostThumb from './PostThumb';
|
||||||
import { IPostThumbResponseData } from '@/app/api/blog/data';
|
import { IPostThumbResponseData } from '@/app/api/blog/data';
|
||||||
import { TLocales } from '@/models/layout';
|
import { TLocales } from '@/models/layout';
|
||||||
import { useTranslations } from 'use-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import routeFactory from '@/assets/constants/routeFactory';
|
import routeFactory from '@/assets/constants/routeFactory';
|
||||||
import SliderThumbSkeleton from '@/components/layout/sliderSkeleton';
|
import SliderThumbSkeleton from '@/components/layout/sliderSkeleton';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user