Files
2026-09-15 20:37:49 +03:30

47 lines
5.8 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useEffect, useRef, useState } from 'react';
import { Menu, X, ArrowUpLeft, Instagram, Mail, ArrowUp } from 'lucide-react';
import { navigation, offices, phones, emails, instagram } from '../lib/content';
import AccountMenu from './account-menu';
export function Brand({branding={},dark=false}) {const src=(dark?branding.logoDarkUrl:branding.logoUrl)||branding.logoUrl||'/Logo.png';return <span className="brand"><img className="brand-logo" src={src} alt="لوگوی ساناز گودرزی" width="462" height="473"/><span className="brand-wordmark"><span className="brand-name">ساناز گودرزی<span className="brand-dot">.</span></span><span className="brand-caption" dir="ltr">ARCHITECTURE & INTERIOR DESIGN</span></span></span>}
export function Header({branding={}}) {
const path=usePathname(); const [open,setOpen]=useState(false); const dialog=useRef(null); const trigger=useRef(null);
useEffect(() => {
const panel = dialog.current;
if (!open && !panel.open) return;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
if (open && !panel.open) panel.showModal();
panel.dataset.phase = open ? 'opening' : 'closing';
const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const animation = panel.animate(
open
? [{ transform: 'translateX(100%)', opacity: .4 }, { transform: 'translateX(0)', opacity: 1 }]
: [{ transform: 'translateX(0)', opacity: 1 }, { transform: 'translateX(100%)', opacity: 0 }],
{ duration: reduced ? 0 : open ? 440 : 260, easing: 'cubic-bezier(.22,1,.36,1)', fill: 'both' }
);
animation.finished.then(() => {
if (!open) {
panel.close();
document.body.style.overflow = previousOverflow;
trigger.current?.focus();
}
}).catch(() => {});
return () => {
animation.cancel();
document.body.style.overflow = previousOverflow;
};
}, [open]);
return <><header className={`site-header ${path==='/'?'over-hero':''}`}><div className="header-inner"><Link href="/" aria-label="گروه معماری ساناز گودرزی، صفحهٔ اصلی"><Brand branding={branding}/></Link><nav className="desktop-nav" aria-label="ناوبری اصلی">{navigation.map(([href,label])=><Link key={href} href={href} aria-current={path===href?'page':undefined}>{label}</Link>)}</nav><div className="header-actions"><AccountMenu/><button ref={trigger} className="menu-button" onClick={()=>setOpen(true)} aria-label="باز کردن منو" aria-expanded={open} aria-controls="mobile-menu"><Menu/></button></div></div></header><dialog id="mobile-menu" className="mobile-menu" ref={dialog} onCancel={event=>{event.preventDefault();setOpen(false)}} onClick={e=>{if(e.target===dialog.current)setOpen(false)}}><div className="menu-top"><Brand branding={branding} dark/><button className="icon-button" aria-label="بستن منو" onClick={()=>setOpen(false)}><X/></button></div><nav aria-label="منوی موبایل">{navigation.map(([href,label],i)=><Link onClick={()=>setOpen(false)} key={href} href={href} aria-current={path===href?'page':undefined}><small>{String(i+1).padStart(2,'0')}</small>{label}<ArrowUpLeft/></Link>)}</nav><a href={`tel:${phones[0].value}`} className="menu-phone" dir="ltr">{phones[0].label}</a></dialog></>;
}
export function Footer({branding={}}) {
const pathname = usePathname();
if (pathname === '/') return null;
return <footer className="site-footer"><div className="reference-footer-main">
<div className="reference-footer-intro"><Link href="/"><Brand branding={branding} dark/></Link><p>این مجموعه در راستای رسیدن به اهداف بزرگ خود در حال وسعت بخشیدن به آتلیه‌های معماری خود می‌باشد.<br/>و در همین راستا در حال تلاش برای طراحی و ساخت بناهای عظیم معماری در این مرزوبوم و خارج از آن می‌باشد و با برنامه‌ریزی و اجرای طرح‌واره‌های هدفمند گام بزرگی را در این مسیر نهاده که به‌زودی همگان شاهد آن خواهیم بود.</p></div>
<div className="reference-footer-details"><div className="footer-contact"><h3>با ما در ارتباط باشید</h3>{phones.map(phone=><a key={phone.value} href={`tel:${phone.value}`} dir="ltr">{phone.label}</a>)}{emails.map(email=><a className="email" key={email} href={`mailto:${email}`} dir="ltr">{email}</a>)}<div className="social-links"><a href={instagram} target="_blank" rel="noreferrer" aria-label="اینستاگرام ساناز گودرزی"><Instagram size={20}/></a><a href={`mailto:${emails[0]}`} aria-label="ارسال ایمیل"><Mail size={20}/></a></div></div>
<div className="footer-offices"><h3>نشانی ما</h3>{offices.map(office=><p key={office.city}>{office.city} — {office.address}{office.latin&&<span dir="ltr">{office.latin}</span>}</p>)}</div></div>
</div><nav className="reference-footer-nav" aria-label="پیوندهای پایین صفحه">{navigation.map(([href,label])=><Link key={href} href={href}>{label}</Link>)}</nav><div className="footer-bottom"><div className="container footer-bottom-bar"><span>گروه معماری ساناز گودرزی</span><a href="https://meshkee.com" target="_blank" rel="noopener noreferrer" dir="ltr" className="meshkee-credit"><span className="meshkee-credit__frame" aria-hidden="true"><i/><i/><i/><i/></span><img src="/meshkee-logo.png" alt="Meshkee" width="42" height="42"/><span className="meshkee-credit__text"><span>Designed And Developed By</span><strong>Meshkee E-Commerce Team</strong></span></a><a className="back-top" href="#main" aria-label="بازگشت به بالای صفحه"><ArrowUp size={18}/></a></div></div></footer>}