Connect Meshkee backend, blog and shared account session
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { cookies } from 'next/headers';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { api, ApiError, getTenant } from '../../../lib/meshkee/api';
|
||||
import { ACCESS_COOKIE,REFRESH_COOKIE,setSessionCookies } from '../../../lib/meshkee/session';
|
||||
type BusinessMembership={businessId?:number|string;id?:number|string;isOwner?:boolean;teamRole?:'admin'|'editor'|'viewer'|null};
|
||||
type User={firstName?:string;lastName?:string;businesses?:BusinessMembership[];isSuperAdmin?:boolean;roles?:string[]};
|
||||
const headers={'Cache-Control':'no-store'};
|
||||
function hasWebsiteAccess(user:User, businessId:number|string){
|
||||
if(user.isSuperAdmin||user.roles?.includes('super_admin'))return true;
|
||||
return user.businesses?.some(membership=>
|
||||
String(membership.businessId??membership.id)===String(businessId)
|
||||
&& (membership.isOwner===true||membership.teamRole==='admin'||membership.teamRole==='editor'||membership.teamRole==='viewer')
|
||||
)??false;
|
||||
}
|
||||
export async function GET(request:Request){
|
||||
const jar=await cookies();const token=jar.get(ACCESS_COOKIE)?.value;const refreshToken=jar.get(REFRESH_COOKIE)?.value;
|
||||
if(!token&&!refreshToken)return NextResponse.json({user:null},{headers});
|
||||
let refreshed:{accessToken:string;refreshToken:string}|undefined;
|
||||
try{
|
||||
let result:{user:User};
|
||||
try{
|
||||
if(!token)throw new ApiError(401);
|
||||
result=await api<{user:User}>('/auth/me',{headers:{Authorization:`Bearer ${token}`}});
|
||||
}catch(error){
|
||||
if(!(error instanceof ApiError)||error.status!==401||!refreshToken)throw error;
|
||||
refreshed=await api<{accessToken:string;refreshToken:string}>('/auth/refresh',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({refreshToken})});
|
||||
if(!refreshed.accessToken||!refreshed.refreshToken)throw new Error('Invalid refresh response');
|
||||
result=await api<{user:User}>('/auth/me',{headers:{Authorization:`Bearer ${refreshed.accessToken}`}});
|
||||
}
|
||||
const tenant=await getTenant();
|
||||
const response=NextResponse.json({user:{name:[result.user.firstName,result.user.lastName].filter(Boolean).join(' ')||'کاربر',isAdmin:hasWebsiteAccess(result.user,tenant.id)}},{headers});
|
||||
if(refreshed)setSessionCookies(response,request,refreshed);
|
||||
return response;
|
||||
}catch(error){return NextResponse.json({user:null},{status:error instanceof ApiError&&error.status===401?401:503,headers})}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import {sameOrigin} from '../../../lib/meshkee/session';
|
||||
import { tenantApi } from '../../../lib/meshkee/api';
|
||||
import { validateContact } from '../../../lib/meshkee/contact';
|
||||
export async function POST(request:Request) {
|
||||
if(!sameOrigin(request))return Response.json({message:'درخواست نامعتبر است.'},{status:403});
|
||||
if(!request.headers.get('content-type')?.includes('application/json'))return Response.json({message:'فرمت درخواست نامعتبر است.'},{status:415});
|
||||
const raw=await request.text();
|
||||
if(raw.length>20000)return Response.json({message:'متن پیام بیش از حد طولانی است.'},{status:413});
|
||||
let input;
|
||||
try{input=JSON.parse(raw)}catch{return Response.json({message:'درخواست نامعتبر است.'},{status:400})}
|
||||
if(!input||typeof input!=='object'||Array.isArray(input))return Response.json({message:'درخواست نامعتبر است.'},{status:400});
|
||||
const {data,errors}=validateContact(input);
|
||||
if(Object.keys(errors).length)return Response.json({message:'اطلاعات فرم را بررسی کنید.',errors},{status:400});
|
||||
try {
|
||||
await tenantApi('/contact-submissions',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(Object.fromEntries(Object.entries(data).filter(([,value])=>value)))});
|
||||
return Response.json({message:'پیام شما با موفقیت ثبت شد. از ارتباط شما سپاسگزاریم.'},{status:201});
|
||||
}catch{return Response.json({message:'پیام ارسال نشد. لطفاً دوباره تلاش کنید یا با ما تماس بگیرید.'},{status:502})}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import {NextResponse} from 'next/server';
|
||||
import { ACCESS_COOKIE,REFRESH_COOKIE,cookieOptions,sameOrigin } from '../../../lib/meshkee/session';
|
||||
export async function POST(request:Request){
|
||||
if(!sameOrigin(request))return NextResponse.json({message:'درخواست نامعتبر است.'},{status:403});
|
||||
const response=NextResponse.json({ok:true});
|
||||
for(const name of [ACCESS_COOKIE,REFRESH_COOKIE]){
|
||||
response.cookies.set(name,'',{...cookieOptions(request),maxAge:0});
|
||||
// Also expire a host-only cookie left by a local/older deployment.
|
||||
if(cookieOptions(request).domain)response.headers.append('Set-Cookie',`${name}=; Path=/; Max-Age=0; HttpOnly; Secure; SameSite=Lax`);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import type {Metadata} from 'next';
|
||||
import Link from 'next/link';
|
||||
import { notFound, redirect } from 'next/navigation';
|
||||
import { ApiError } from '../../../../lib/meshkee/api';
|
||||
import { getBlog, titleSlug, blogHref, summary, cover, articleHtml } from '../../../../lib/meshkee/blog';
|
||||
type Props={params:Promise<{id:string;slug:string}>};
|
||||
export const dynamic='force-dynamic';
|
||||
export async function generateMetadata({params}:Props):Promise<Metadata>{
|
||||
try {const {id}=await params;const post=await getBlog(id);return {title:post.title,description:summary(post)||`${post.title}؛ مجله سلامت گستر اعتماد`,alternates:{canonical:`https://sgemed.com${blogHref(post)}`}}}catch{return {title:'مطلب',robots:{index:false}}}
|
||||
}
|
||||
export default async function Article({params}:Props){
|
||||
const {id,slug}=await params;
|
||||
let post;
|
||||
try{post=await getBlog(id)}catch(error){if(error instanceof ApiError&&error.status===404)notFound();throw error}
|
||||
if(slug!==titleSlug(post.title))redirect(blogHref(post));
|
||||
return <><section className="pagehead"><div className="wrap"><Link className="eyebrow" href="/blog">مجله سلامت گستر ←</Link><h1>{post.title}</h1></div></section><article className="wrap section blog-article">{cover(post)&&<img className="article-cover" src={cover(post)} alt={post.title}/>}<div className="article-body" dangerouslySetInnerHTML={{__html:articleHtml(post)}}/><Link className="textlink" href="/blog">بازگشت به مجله ←</Link></article></>;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
'use client';
|
||||
export default function ErrorPage({reset}:{reset:()=>void}) {return <section className="wrap section backend-empty"><h1>دریافت مطلب ممکن نشد</h1><p>ارتباط با مجله برقرار نشد. لطفاً دوباره تلاش کنید.</p><button className="button" onClick={reset}>تلاش دوباره</button></section>}
|
||||
@@ -0,0 +1 @@
|
||||
export default function Loading(){return <div className="wrap section backend-empty" role="status">در حال دریافت مطالب…</div>}
|
||||
@@ -0,0 +1,2 @@
|
||||
import Link from 'next/link';
|
||||
export default function Missing(){return <section className="wrap section backend-empty"><h1>مطلب پیدا نشد</h1><p>این مطلب در دسترس نیست یا هنوز منتشر نشده است.</p><Link href="/blog" className="button">بازگشت به مجله</Link></section>}
|
||||
@@ -0,0 +1,12 @@
|
||||
import Link from 'next/link';
|
||||
import { BookOpen, ArrowUpLeft } from 'lucide-react';
|
||||
import { getBlogs, blogHref, summary, cover } from '../../lib/meshkee/blog';
|
||||
export const metadata = {title:'مجله سلامت گستر',description:'مقالات و تازههای سلامت گستر اعتماد در زمینه استریلیزاسیون، تجهیزات پزشکی و کنترل عفونت.'};
|
||||
export const dynamic = 'force-dynamic';
|
||||
export default async function BlogPage({searchParams}:{searchParams:Promise<{page?:string}>}) {
|
||||
const query=await searchParams; const page=Math.max(1,Math.min(10000,Number.parseInt(query.page||'1',10)||1));
|
||||
let data;
|
||||
try{data=await getBlogs(page)}catch{return <><Banner/><section className="wrap section backend-empty"><BookOpen size={32}/><h2>دریافت مطالب ممکن نشد</h2><p>لطفاً کمی بعد دوباره تلاش کنید.</p><a className="button" href="/blog">تلاش دوباره</a></section></>}
|
||||
return <><Banner/><section className="wrap section">{data.items.length ? <div className="blog-grid">{data.items.map(post=><Link className="blog-card" href={blogHref(post)} key={post.id}>{cover(post)?<img src={cover(post)} alt={post.title}/>:<div className="blog-placeholder"><BookOpen size={38} strokeWidth={1}/></div>}<div className="blog-card-copy"><h2>{post.title}</h2><p>{summary(post)}</p><span>مطالعه مطلب <ArrowUpLeft size={18}/></span></div></Link>)}</div>:<div className="backend-empty"><BookOpen size={36} strokeWidth={1.3}/><h2>بهزودی با مطالب تازه همراه شما هستیم</h2><p>هنوز مطلبی منتشر نشده است.</p></div>}{data.total>12&&<nav className="blog-pagination" aria-label="صفحهبندی مجله">{page>1&&<Link href={`/blog?page=${page-1}`}>صفحه قبل</Link>}<span>صفحه {page.toLocaleString('fa-IR')}</span>{page*12<data.total&&<Link href={`/blog?page=${page+1}`}>صفحه بعد</Link>}</nav>}</section></>;
|
||||
}
|
||||
function Banner(){return <section className="pagehead"><div className="wrap"><span className="eyebrow">SGE JOURNAL</span><h1>مجله سلامت گستر</h1><p>دانش و تازههای استریلیزاسیون و کنترل عفونت</p></div></section>}
|
||||
File diff suppressed because one or more lines are too long
+6
-2
@@ -1,7 +1,11 @@
|
||||
import AccountMenu from '../components/backend/account-menu';
|
||||
import type { Metadata } from 'next';
|
||||
import Link from 'next/link';
|
||||
import './globals.css';
|
||||
export const metadata: Metadata = { title: { default: 'سلامت گستر اعتماد | تجهیزات استریل و کنترل عفونت', template: '%s | سلامت گستر اعتماد' }, description: 'شرکت مهندسی سلامت گستر اعتماد؛ مشاور و مجری استریل و کنترل عفونت. محصولات تخصصی، کاتالوگها و راههای ارتباط با ما.' };
|
||||
import { getFavicon } from '../lib/meshkee/api';
|
||||
import ProductMenu from '../components/product-menu';
|
||||
const baseMetadata: Metadata = { title: { default: 'سلامت گستر اعتماد | تجهیزات استریل و کنترل عفونت', template: '%s | سلامت گستر اعتماد' }, description: 'شرکت مهندسی سلامت گستر اعتماد؛ مشاور و مجری استریل و کنترل عفونت. محصولات تخصصی، کاتالوگها و راههای ارتباط با ما.' };
|
||||
export async function generateMetadata(): Promise<Metadata> { return { ...baseMetadata, icons: { icon: await getFavicon() } }; }
|
||||
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
return <html lang="fa" dir="rtl"><body><div className="topbar"><div className="wrap"><span>مشاور و مجری استریل و کنترل عفونت</span><a href="tel:02166157609">دفتر تهران <b dir="ltr">۰۲۱ − ۶۶۱۵۷۶۰۹</b></a></div></div><header className="wrap header"><Link className="brand" href="/" aria-label="سلامت گستر اعتماد، صفحه اصلی"><img src="/images/logo.png" alt="SGE Medical Group" /></Link><nav aria-label="منوی اصلی"><Link href="/">صفحه اصلی</Link><Link href="/#products">محصولات</Link><Link href="/about-us">درباره ما</Link><Link href="/tmas-bama">تماس با ما</Link></nav><Link className="button small" href="/tmas-bama">مشاوره و خرید <span>↖</span></Link></header><main>{children}</main><footer><div className="wrap footergrid"><div><img className="footerlogo" src="/images/logo.png" alt="سلامت گستر اعتماد"/><h3>شرکت مهندسی سلامت گستر اعتماد</h3><p>همراه شما در مسیر استریلیزاسیون<br/>و کنترل عفونت</p></div><div><h3>دسترسی سریع</h3><Link href="/">صفحه اصلی</Link><Link href="/#products">محصولات و کاتالوگها</Link><Link href="/about-us">درباره ما</Link><Link href="/tmas-bama">تماس با ما</Link></div><div><h3>با ما در ارتباط باشید</h3><a href="tel:02166157609">دفتر تهران: <b dir="ltr">۰۲۱۶۶۱۵۷۶۰۹</b></a><a href="tel:02532891573">دفتر شهرستانها: <b dir="ltr">۰۲۵۳۲۸۹۱۵۷۳</b></a><a href="mailto:sale.steril@gmail.com">sale.steril@gmail.com</a><a href="https://t.me/CCSD1" target="_blank" rel="noreferrer">تلگرام ↗</a></div></div><div className="wrap copyright"><span>تمامی حقوق برای سلامت گستر اعتماد محفوظ است.</span><span dir="ltr">SGE MEDICAL GROUP</span></div></footer></body></html>
|
||||
return <html lang="fa" dir="rtl"><body><div className="topbar"><div className="wrap"><span>مشاور و مجری استریل و کنترل عفونت</span><a href="tel:02166157609">دفتر تهران <b dir="ltr">۰۲۱ − ۶۶۱۵۷۶۰۹</b></a></div></div><header className="wrap header"><Link className="brand" href="/" aria-label="سلامت گستر اعتماد، صفحه اصلی"><img src="/images/logo.png" alt="SGE Medical Group" /></Link><nav aria-label="منوی اصلی"><Link href="/">صفحه اصلی</Link><ProductMenu /><Link href="/blog">مجله</Link><Link href="/about-us">درباره ما</Link><Link href="/tmas-bama">تماس با ما</Link></nav><AccountMenu /><Link className="button small" href="/tmas-bama">مشاوره و خرید <span>↖</span></Link></header><main>{children}</main><footer><div className="wrap footergrid"><div><img className="footerlogo" src="/images/logo.png" alt="سلامت گستر اعتماد"/><h3>شرکت مهندسی سلامت گستر اعتماد</h3><p>همراه شما در مسیر استریلیزاسیون<br/>و کنترل عفونت</p></div><div><h3>دسترسی سریع</h3><Link href="/">صفحه اصلی</Link><Link href="/#products">محصولات و کاتالوگها</Link><Link href="/blog">مجله</Link><Link href="/about-us">درباره ما</Link><Link href="/tmas-bama">تماس با ما</Link></div><div><h3>با ما در ارتباط باشید</h3><a href="tel:02166157609">دفتر تهران: <b dir="ltr">۰۲۱۶۶۱۵۷۶۰۹</b></a><a href="tel:02532891573">دفتر شهرستانها: <b dir="ltr">۰۲۵۳۲۸۹۱۵۷۳</b></a><a href="mailto:sale.steril@gmail.com">sale.steril@gmail.com</a><a href="https://t.me/CCSD1" target="_blank" rel="noreferrer">تلگرام ↗</a></div></div><div className="wrap copyright"><span>تمامی حقوق برای سلامت گستر اعتماد محفوظ است.</span><span dir="ltr">SGE MEDICAL GROUP</span></div></footer></body></html>
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
import HeroSlider from '../components/hero-slider';
|
||||
import Link from 'next/link';
|
||||
import { FlaskConical, ShieldCheck, Package, Microscope, ArrowDownLeft, MoveLeft } from 'lucide-react';
|
||||
import catalog from './catalog.json';
|
||||
const groups=[{title:'اندیکاتورهای شیمیایی',en:'Chemical indicators',icon:FlaskConical,start:2,end:15},{title:'اندیکاتورهای بیولوژیکال',en:'Biological indicators',icon:Microscope,start:0,end:2},{title:'بستهبندی استریل',en:'Sterile packaging',icon:Package,start:15,end:26},{title:'بهداشت و کنترل عفونت',en:'Infection control',icon:ShieldCheck,start:26,end:30}];
|
||||
export default function Home(){return <><section className="hero"><div className="hero-photo"><img src="/images/laboratory.jpg" alt="محیط آزمایشگاهی و تجهیزات تخصصی"/><div className="photo-label"><span className="cross">+</span><div>دانش، دقت، اعتماد<small>SCIENCE IN SERVICE OF HEALTH</small></div></div></div><div className="hero-copy"><span className="eyebrow">SGE MEDICAL GROUP <i/></span><h1>اعتماد، نخستین گام<br/>در مسیر <em>سلامت.</em></h1><p>راهکارهای تخصصی استریلیزاسیون و کنترل عفونت؛<br/>همراه مراکز درمانی، از انتخاب تا استفاده.</p><div className="actions"><a className="button" href="#products">محصولات تخصصی ما <MoveLeft size={19}/></a><Link className="textlink" href="/about-us">آشنایی با سلامت گستر <ArrowDownLeft size={19}/></Link></div><div className="hero-bottom"><ShieldCheck size={25}/><span>شرکت مهندسی سلامت گستر اعتماد<small>مشاور و مجری استریل و کنترل عفونت</small></span></div></div></section><div className="wrap categories">{groups.map((g,i)=><a href={'#group-'+i} key={g.title}><g.icon size={30} strokeWidth={1.4}/><div><strong>{g.title}</strong><small>{g.en}</small></div><ArrowDownLeft size={17}/></a>)}</div><section className="wrap section" id="products"><div className="section-heading"><div><span className="eyebrow">محصولات تخصصی ما</span><h2>دقت در انتخاب؛ اطمینان در عملکرد</h2></div><p>معرفی محصولات و دریافت کاتالوگهای تخصصی<br/>استریل، بستهبندی و کنترل عفونت</p></div><div className="catalog">{groups.map((g,i)=><details id={'group-'+i} key={g.title} open={i===0}><summary><span className="group-title"><g.icon size={24}/>{g.title}<small>{g.en}</small></span><span>مشاهده محصولات +</span></summary><div className="product-grid">{catalog.slice(g.start,g.end).map(p=><a className="product" href={p.downloaded ? p.url : '/tmas-bama'} key={p.source} target="_blank" rel="noreferrer"><span className="pdf">PDF</span><h3>{p.title}</h3><span className="download">{p.downloaded ? 'دریافت کاتالوگ' : 'درخواست کاتالوگ'} <ArrowDownLeft size={18}/></span></a>)}</div></details>)}</div></section><section className="education"><div className="wrap split"><img src="/images/care.jpg" alt="فعالیت متخصصان در محیط پزشکی"/><div><span className="eyebrow">دانش، پایهٔ مراقبت بهتر</span><h2>آموزش، کلید توسعه<br/>و تخصص ما است.</h2><p>دانش استریل و بازفرآوری ابزار پزشکی، دانشی چندبعدی و تخصصی است. کتاب راهنمای جامع استریلیزاسیون، ترجمه گایدلاین ST79، برای فعالان حوزه استریل و کارشناسان کنترل عفونت معرفی شده است.</p><Link href="/tmas-bama" className="textlink">برای تهیه کتاب با ما تماس بگیرید <MoveLeft size={20}/></Link></div></div></section><section className="wrap section info"><span className="eyebrow">استریل و کنترل عفونت</span><h2>شناخت بهتر، انتخاب آگاهانهتر</h2><div className="info-grid"><article><span>۰۱ / CHEMICAL</span><h3>اندیکاتور شیمیایی چیست؟</h3><p>این نشانگرها معمولاً جامد و کاغذیشکل هستند، داخل پکهای استریل قرار میگیرند و در طول فرایند استریلیزاسیون تغییر رنگ میدهند.</p></article><article><span>۰۲ / BIOLOGICAL</span><h3>اندیکاتور بیولوژیکال چیست؟</h3><p>این اندیکاتورها حاوی میکروارگانیسمهای زنده هستند. نتیجه کشت آنها در محیط مرتبط، برای ارزیابی عملکرد فرایند استریلیزاسیون استفاده میشود.</p></article><article><span>۰۳ / DOCUMENTATION</span><h3>مستندسازی و ردیابی استریل</h3><p>نرمافزار CSSD-DOC برای مستندسازی و ردیابی استریل؛ گذار از دنیای کاغذی به عصر الکترونیک.</p><Link href="/tmas-bama">دریافت اطلاعات بیشتر ←</Link></article></div></section><section className="contactband"><div className="wrap"><div><h2>برای انتخاب محصول مناسب، همراه شما هستیم.</h2><p>مشاوره و خرید محصولات تخصصی کنترل عفونت و استریلیزاسیون</p></div><Link href="/tmas-bama" className="button white">ارتباط با کارشناسان <MoveLeft size={20}/></Link></div></section></>}
|
||||
export default function Home(){return <><HeroSlider /><div className="wrap categories">{groups.map((g,i)=><a href={'#group-'+i} key={g.title}><g.icon size={30} strokeWidth={1.4}/><div><strong>{g.title}</strong><small>{g.en}</small></div><ArrowDownLeft size={17}/></a>)}</div><section className="wrap section" id="products"><div className="section-heading"><div><span className="eyebrow">محصولات تخصصی ما</span><h2>دقت در انتخاب؛ اطمینان در عملکرد</h2></div><p>معرفی محصولات و دریافت کاتالوگهای تخصصی<br/>استریل، بستهبندی و کنترل عفونت</p></div><div className="catalog">{groups.map((g,i)=><details id={'group-'+i} key={g.title} open={i===0}><summary><span className="group-title"><g.icon size={24}/>{g.title}<small>{g.en}</small></span><span>مشاهده محصولات +</span></summary><div className="product-grid">{catalog.slice(g.start,g.end).map(p=><a className="product" href={p.downloaded ? p.url : '/tmas-bama'} key={p.source} target="_blank" rel="noreferrer"><span className="pdf">PDF</span><h3>{p.title}</h3><span className="download">{p.downloaded ? 'دریافت کاتالوگ' : 'درخواست کاتالوگ'} <ArrowDownLeft size={18}/></span></a>)}</div></details>)}</div></section><section className="education"><div className="wrap split"><img src="/images/care.jpg" alt="فعالیت متخصصان در محیط پزشکی"/><div><span className="eyebrow">دانش، پایهٔ مراقبت بهتر</span><h2>آموزش، کلید توسعه<br/>و تخصص ما است.</h2><p>دانش استریل و بازفرآوری ابزار پزشکی، دانشی چندبعدی و تخصصی است. کتاب راهنمای جامع استریلیزاسیون، ترجمه گایدلاین ST79، برای فعالان حوزه استریل و کارشناسان کنترل عفونت معرفی شده است.</p><Link href="/tmas-bama" className="textlink">برای تهیه کتاب با ما تماس بگیرید <MoveLeft size={20}/></Link></div></div></section><section className="wrap section info"><span className="eyebrow">استریل و کنترل عفونت</span><h2>شناخت بهتر، انتخاب آگاهانهتر</h2><div className="info-grid"><article><span>۰۱ / CHEMICAL</span><h3>اندیکاتور شیمیایی چیست؟</h3><p>این نشانگرها معمولاً جامد و کاغذیشکل هستند، داخل پکهای استریل قرار میگیرند و در طول فرایند استریلیزاسیون تغییر رنگ میدهند.</p></article><article><span>۰۲ / BIOLOGICAL</span><h3>اندیکاتور بیولوژیکال چیست؟</h3><p>این اندیکاتورها حاوی میکروارگانیسمهای زنده هستند. نتیجه کشت آنها در محیط م��تبط، برای ارزیابی عملکرد فرایند استریلیزاسیون استفاده میشود.</p></article><article><span>۰۳ / DOCUMENTATION</span><h3>مستندسازی و ردیابی استریل</h3><p>نرمافزار CSSD-DOC برای مستندسازی و ردیابی استریل؛ گذار از دنیای کاغذی به عصر الکترونیک.</p><Link href="/tmas-bama">دریافت اطلاعات بیشتر ←</Link></article></div></section><section className="contactband"><div className="wrap"><div><h2>برای انتخاب محصول مناسب، همراه شما هستیم.</h2><p>مشاوره و خرید محصولات تخصصی کنترل عفونت و استریلیزاسیون</p></div><Link href="/tmas-bama" className="button white">ارتباط با کارشناسان <MoveLeft size={20}/></Link></div></section></>}
|
||||
|
||||
+31
-2
@@ -1,2 +1,31 @@
|
||||
export const metadata={title:'تماس با ما'};
|
||||
export default function Contact(){return <><section className="pagehead"><div className="wrap"><span className="eyebrow">CONTACT US</span><h1>با ما در تماس باشید</h1><p>برای مشاوره و خرید محصولات کنترل عفونت و استریلیزاسیون، همراه شما هستیم.</p></div></section><section className="wrap section"><div className="section-heading"><div><span className="eyebrow">راههای ارتباطی</span><h2>گفتوگو، آغاز یک انتخاب مطمئن</h2></div><p>شرکت مهندسی سلامت گستر اعتماد<br/>مشاور و مجری استریل و کنترل عفونت</p></div><div className="contactcards"><article className="contactcard"><span className="eyebrow">۰۱ / CALL</span><h2>شمارههای تماس دفاتر</h2><small>دفتر تهران</small><a href="tel:02166157609" dir="ltr">021 6615 7609</a><small>دفتر شهرستانها</small><a href="tel:02532891573" dir="ltr">025 3289 1573</a><a href="tel:02536550178" dir="ltr">025 3655 0178</a></article><article className="contactcard"><span className="eyebrow">۰۲ / MOBILE</span><h2>ارتباط با کارشناسان</h2><small>آقای مهندس اویسی</small><a href="tel:09125537630" dir="ltr">0912 553 7630</a><small>خانم مهندس یعقوبی راد</small><a href="tel:09389221460" dir="ltr">0938 922 1460</a></article><article className="contactcard"><span className="eyebrow">۰۳ / NETWORKS</span><h2>با ما همراه باشید</h2><small>پست الکترونیکی</small><a href="mailto:sale.steril@gmail.com">sale.steril@gmail.com</a><small>کانال تلگرام</small><a href="https://t.me/CCSD1" target="_blank" rel="noreferrer" dir="ltr">@CCSD1 ↗</a></article><article className="contactcard"><span className="eyebrow">۰۴ / FAX</span><h2>شماره فکس</h2><p>ارسال مکاتبات و اسناد</p><span dir="ltr" style={{display:'block',fontSize:23,color:'#0088a4'}}>025 3655 0166</span></article></div></section></>}
|
||||
import ContactForm from '../../components/backend/contact-form';
|
||||
import { Phone, Headphones, Mail, Send, Printer, ArrowUpLeft } from 'lucide-react';
|
||||
|
||||
export const metadata = { title: 'تماس با ما' };
|
||||
|
||||
export default function Contact() {
|
||||
return <>
|
||||
<section className="pagehead"><div className="wrap"><span className="eyebrow">CONTACT US</span><h1>با ما در تماس باشید</h1><p>برای مشاوره و خرید محصولات کنترل عفونت و استریلیزاسیون، همراه شما هستیم.</p></div></section>
|
||||
<section className="wrap section contact-section">
|
||||
<div className="section-heading"><div><span className="eyebrow">راههای ارتباطی</span><h2>گفتوگو، آغاز یک انتخاب مطمئن</h2></div><p>شرکت مهندسی سلامت گستر اعتماد<br/>مشاور و مجری استریل و کنترل عفونت</p></div>
|
||||
<div className="contact-primary">
|
||||
<article className="contact-panel office-panel">
|
||||
<div className="contact-panel-heading"><span className="contact-icon"><Phone size={24} strokeWidth={1.5}/></span><div><span className="eyebrow">OFFICES</span><h2>تماس با دفاتر</h2></div></div>
|
||||
<div className="contact-line"><span>دفتر تهران</span><a href="tel:02166157609" aria-label="تماس با دفتر تهران"><bdi>021 6615 7609</bdi><ArrowUpLeft size={17}/></a></div>
|
||||
<div className="contact-line"><span>دفتر شهرستانها</span><div className="contact-numbers"><a href="tel:02532891573" aria-label="تماس با دفتر شهرستانها، خط اول"><bdi>025 3289 1573</bdi><ArrowUpLeft size={17}/></a><a href="tel:02536550178" aria-label="تماس با دفتر شهرستانها، خط دوم"><bdi>025 3655 0178</bdi><ArrowUpLeft size={17}/></a></div></div>
|
||||
</article>
|
||||
<article className="contact-panel expert-panel">
|
||||
<div className="contact-panel-heading"><span className="contact-icon"><Headphones size={25} strokeWidth={1.5}/></span><div><span className="eyebrow">OUR EXPERTS</span><h2>ارتباط مستقیم با کارشناسان</h2></div></div>
|
||||
<div className="contact-line"><span>آقای مهندس اویسی</span><a href="tel:09125537630" aria-label="تماس با مهندس اویسی"><bdi>0912 553 7630</bdi><ArrowUpLeft size={17}/></a></div>
|
||||
<div className="contact-line"><span>خانم مهندس یعقوبی راد</span><a href="tel:09389221460" aria-label="تماس با مهندس یعقوبی راد"><bdi>0938 922 1460</bdi><ArrowUpLeft size={17}/></a></div>
|
||||
</article>
|
||||
</div>
|
||||
<div className="contact-secondary">
|
||||
<a className="contact-channel" href="mailto:sale.steril@gmail.com"><span className="channel-icon"><Mail size={23} strokeWidth={1.5}/></span><div><h3>پست الکترونیکی</h3><bdi>sale.steril@gmail.com</bdi></div><ArrowUpLeft className="channel-arrow" size={18}/></a>
|
||||
<a className="contact-channel" href="https://t.me/CCSD1" target="_blank" rel="noreferrer"><span className="channel-icon"><Send size={23} strokeWidth={1.5}/></span><div><h3>همراه ما در تلگرام</h3><bdi>@CCSD1</bdi></div><ArrowUpLeft className="channel-arrow" size={18}/></a>
|
||||
<div className="contact-channel fax-channel"><span className="channel-icon"><Printer size={23} strokeWidth={1.5}/></span><div><h3>فکس · مکاتبات و اسناد</h3><bdi>025 3655 0166</bdi></div></div>
|
||||
</div>
|
||||
<ContactForm />
|
||||
</section>
|
||||
</>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user