about
This commit is contained in:
@@ -7,27 +7,33 @@ import { TabHeader } from '@/components/tab/TabHeader';
|
||||
import Comment from '@/components/utils/Comment';
|
||||
import RateBar from '@/components/utils/RateBar';
|
||||
import useToggle from '@/hooks/helpers/useToggle';
|
||||
import { AboutDataModel } from '@/lib/api/info/getAboutData';
|
||||
import { ArrowDown2, CallCalling, Clock, Gallery, InfoCircle, Instagram, Location, Star1, Whatsapp } from 'iconsax-react';
|
||||
import { CallCalling, Gallery, InfoCircle, Instagram, Location, Star1, Whatsapp } from 'iconsax-react';
|
||||
import { useQueryState } from 'next-usequerystate';
|
||||
import Image from 'next/image';
|
||||
import React from 'react'
|
||||
import { useGetAbout, useGetReviews } from './hooks/useAboutData';
|
||||
|
||||
const sortings = [
|
||||
'جدیدترین',
|
||||
'قدیمی ترین'
|
||||
]
|
||||
|
||||
function AboutPage({ data }: Readonly<{ data: AboutDataModel; }>) {
|
||||
function AboutPage() {
|
||||
|
||||
const { data: aboutData } = useGetAbout();
|
||||
const { data: reviewsData } = useGetReviews();
|
||||
const [sorting, setSorting] = useQueryState('sortBy', { defaultValue: '0' });
|
||||
const { state: sortingModal, toggle: toggleSortingModal, set: setSortingModal } = useToggle();
|
||||
|
||||
const restaurant = aboutData?.data;
|
||||
|
||||
const changeSorting = (index: number) => {
|
||||
setSorting(() => String(index));
|
||||
setSortingModal(false);
|
||||
}
|
||||
|
||||
const firstTab = () => {
|
||||
if (!restaurant) return null;
|
||||
|
||||
return (
|
||||
<section aria-labelledby="about-title" className='py-4'>
|
||||
@@ -35,100 +41,84 @@ function AboutPage({ data }: Readonly<{ data: AboutDataModel; }>) {
|
||||
className="bg-container rounded-container shadow-container p-4">
|
||||
<div className="flex justify-between items-center border-b-[1.5px] border-gray-200 pb-[25px]">
|
||||
<div className="">
|
||||
<h2 className='text-sm2 font-bold leading-5'>{data.title_fa}</h2>
|
||||
<p className="text-sm2 leading-5 mt-4">تاسیس: {data.foundationDate}</p>
|
||||
<p className="text-sm2 leading-5 mt-2">نوع محصولات: {data.offering}</p>
|
||||
<h2 className='text-sm2 font-bold leading-5'>{restaurant.name}</h2>
|
||||
{restaurant.establishedYear && (
|
||||
<p className="text-sm2 leading-5 mt-4">تاسیس: {restaurant.establishedYear}</p>
|
||||
)}
|
||||
{restaurant.tagNames && restaurant.tagNames.length > 0 && (
|
||||
<p className="text-sm2 leading-5 mt-2">نوع محصولات: {restaurant.tagNames.join('، ')}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="rounded-normal overflow-clip">
|
||||
<Image
|
||||
alt='logo'
|
||||
src={'/assets/images/food-preview.png'}
|
||||
width={88}
|
||||
height={88}
|
||||
unoptimized
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-[23px]">
|
||||
<h3 className="text-sm2 font-bold leading-5">درباره مجموعه</h3>
|
||||
<p className="text-sm2 leading-5 mt-3 border-spacing-48" style={{ wordSpacing: '0.01em' }}>
|
||||
{data.description}
|
||||
</p>
|
||||
<div className='inline-flex gap-2 mt-[23px] items-center'>
|
||||
<Gallery size={20} className='stroke-disabled-text' />
|
||||
<span className='text-sm2 text-disabled-text font-medium pt-0.5'>عکس های رستوران</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className="bg-container rounded-container shadow-container pt-3 pb-3.5 px-[16px] mt-4 grid grid-cols-3 items-center">
|
||||
<h2 className='text-sm2 font-medium leading-5'>ارتباط</h2>
|
||||
<div className='col-span-1 text-center flex justify-center gap-4'>
|
||||
{data.contacts.phone &&
|
||||
<a href={`tel://${data.contacts.phone}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<CallCalling className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
{data.contacts.telegram &&
|
||||
<a href={`https://t.me/${data.contacts.telegram}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<TelegramIcon className='stroke-foreground' width={24} height={24} />
|
||||
</a>
|
||||
}
|
||||
{data.contacts.whatsapp &&
|
||||
<a href={`https://whatsapp.com/?phone=${data.contacts.whatsapp}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<Whatsapp className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
{data.contacts.instagram &&
|
||||
<a href={`https://instagram.com/${data.contacts.instagram}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<Instagram className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-container rounded-container shadow-container px-4 pt-6 pb-6 mt-4">
|
||||
<h2 className='text-sm2 font-medium leading-5'>آدرس</h2>
|
||||
<p className='text-sm2 mt-[9px] leading-5'>{data.address}</p>
|
||||
<div className='inline-flex gap-2 mt-[23px] items-center '>
|
||||
<Location size={20} className='stroke-disabled-text' />
|
||||
<span className='text-sm2 text-disabled-text '>عکس های رستوران</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
aria-label='ساعات کاری'
|
||||
className="bg-container rounded-container shadow-container py-6 px-4 mt-4 flex justify-between items-center">
|
||||
<div className="flex items-center gap-2 justify-start">
|
||||
<Clock size={16} className='stroke-disabled-text' />
|
||||
<div className='text-sm2 font-medium leading-5 mt-0.5 text-[#8C90A3]'>باز</div>
|
||||
<div className='size-1.5 bg-[#D9D9D9] rounded-full'></div>
|
||||
<div className='text-sm2 mt-0.5'>امروز از ساعت 10:30 تا 17:30 </div>
|
||||
</div>
|
||||
<div className="">
|
||||
<ArrowDown2 size={16} className='stroke-[#292D32]' />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
{data.open.map((v, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
style={{ boxShadow: '0px 0px 14px 0px #0000000F' }}
|
||||
className="bg-[#F6F6FA] dark:bg-border rounded-container leading-5 py-6 px-4 mt-4 flex justify-between items-center">
|
||||
<div className="text-sm2">
|
||||
{v.day}
|
||||
</div>
|
||||
<div className='text-sm2 font-light'>
|
||||
{v.close} - {v.open}
|
||||
</div>
|
||||
{restaurant.logo && (
|
||||
<div className="rounded-normal overflow-clip">
|
||||
<Image
|
||||
alt='logo'
|
||||
src={restaurant.logo}
|
||||
width={88}
|
||||
height={88}
|
||||
unoptimized
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
)}
|
||||
</div>
|
||||
{restaurant.description && (
|
||||
<div className="mt-[23px]">
|
||||
<h3 className="text-sm2 font-bold leading-5">درباره مجموعه</h3>
|
||||
<p className="text-sm2 leading-5 mt-3 border-spacing-48" style={{ wordSpacing: '0.01em' }}>
|
||||
{restaurant.description}
|
||||
</p>
|
||||
{restaurant.images && restaurant.images.length > 0 && (
|
||||
<div className='inline-flex gap-2 mt-[23px] items-center'>
|
||||
<Gallery size={20} className='stroke-disabled-text' />
|
||||
<span className='text-sm2 text-disabled-text font-medium pt-0.5'>عکس های رستوران</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{(restaurant.phone || restaurant.telegram || restaurant.whatsapp || restaurant.instagram) && (
|
||||
<section
|
||||
className="bg-container rounded-container shadow-container pt-3 pb-3.5 px-[16px] mt-4 grid grid-cols-3 items-center">
|
||||
<h2 className='text-sm2 font-medium leading-5'>ارتباط</h2>
|
||||
<div className='col-span-1 text-center flex justify-center gap-4'>
|
||||
{restaurant.phone &&
|
||||
<a href={`tel://${restaurant.phone}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<CallCalling className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
{restaurant.telegram &&
|
||||
<a href={`https://t.me/${restaurant.telegram}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<TelegramIcon className='stroke-foreground' width={24} height={24} />
|
||||
</a>
|
||||
}
|
||||
{restaurant.whatsapp &&
|
||||
<a href={`https://whatsapp.com/?phone=${restaurant.whatsapp}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<Whatsapp className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
{restaurant.instagram &&
|
||||
<a href={`https://instagram.com/${restaurant.instagram}`} className='bg-[#EAEDF5] dark:bg-neutral-700 p-2 rounded-normal'>
|
||||
<Instagram className='stroke-foreground' size={24} />
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{restaurant.address && (
|
||||
<section className="bg-container rounded-container shadow-container px-4 pt-6 pb-6 mt-4">
|
||||
<h2 className='text-sm2 font-medium leading-5'>آدرس</h2>
|
||||
<p className='text-sm2 mt-[9px] leading-5'>{restaurant.address}</p>
|
||||
{restaurant.latitude && restaurant.longitude && (
|
||||
<div className='inline-flex gap-2 mt-[23px] items-center '>
|
||||
<Location size={20} className='stroke-disabled-text' />
|
||||
<span className='text-sm2 text-disabled-text '>موقعیت روی نقشه</span>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
)}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import * as api from "../service/AboutService";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
export const useGetAbout = () => {
|
||||
const { name } = useParams<{ name: string }>();
|
||||
return useQuery({
|
||||
queryKey: ["about"],
|
||||
queryFn: () => api.getAbout(name),
|
||||
enabled: !!name,
|
||||
retry: false,
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetReviews = () => {
|
||||
const { name } = useParams<{ name: string }>();
|
||||
return useQuery({
|
||||
queryKey: ["reviews"],
|
||||
queryFn: () => api.getReviews(name),
|
||||
enabled: !!name,
|
||||
retry: false,
|
||||
});
|
||||
};
|
||||
@@ -1,14 +1,10 @@
|
||||
import React from 'react';
|
||||
import AboutPage from './AboutPage';
|
||||
import { getAboutData } from '@/lib/api/info/getAboutData';
|
||||
|
||||
type Params = { name: string };
|
||||
|
||||
export default async function Page({ params }: { params: Promise<Params> }) {
|
||||
const { name } = await params;
|
||||
const data = await getAboutData(name);
|
||||
import React from 'react'
|
||||
import AboutPage from './AboutPage'
|
||||
|
||||
const page = () => {
|
||||
return (
|
||||
<><AboutPage data={data} /></>
|
||||
);
|
||||
<AboutPage />
|
||||
)
|
||||
}
|
||||
|
||||
export default page
|
||||
@@ -0,0 +1,12 @@
|
||||
import { api } from "@/config/axios";
|
||||
import { AboutResponse } from "../types/Types";
|
||||
|
||||
export const getAbout = async (name: string): Promise<AboutResponse> => {
|
||||
const { data } = await api.get<AboutResponse>(`/public/restaurants/${name}`);
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getReviews = async (name: string) => {
|
||||
const { data } = await api.get(`/public/reviews/restuarant/${name}`);
|
||||
return data;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { BaseResponse } from "@/app/[name]/(Main)/types/Types";
|
||||
|
||||
export interface ServiceArea {
|
||||
type: "Polygon";
|
||||
coordinates: number[][][];
|
||||
}
|
||||
|
||||
export interface Restaurant {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
logo: string | null;
|
||||
address: string | null;
|
||||
menuColor: string | null;
|
||||
latitude: number | null;
|
||||
longitude: number | null;
|
||||
serviceArea: ServiceArea;
|
||||
establishedYear: number | null;
|
||||
phoneNumber: string | null;
|
||||
phone: string;
|
||||
instagram: string | null;
|
||||
telegram: string | null;
|
||||
whatsapp: string | null;
|
||||
description: string | null;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
tagNames: string[] | null;
|
||||
images: string[] | null;
|
||||
vat: number;
|
||||
}
|
||||
|
||||
export type AboutResponse = BaseResponse<Restaurant>;
|
||||
Reference in New Issue
Block a user