|
@@ -0,0 +1,69 @@
|
|
|
|
|
+import { useEffect, useState } from 'react'
|
|
|
|
|
+import { Link, useParams } from 'react-router-dom'
|
|
|
|
|
+import { Helmet } from 'react-helmet-async'
|
|
|
|
|
+import { getCustomerById, type CustomerDetailEntity } from '../../../services/api/customers'
|
|
|
|
|
+import { usePageContext } from '../../../shared/pageContext'
|
|
|
|
|
+import { DashboardLayout } from '../../../layouts/DashboardLayout'
|
|
|
|
|
+
|
|
|
|
|
+function getDisplayValue(value?: string) {
|
|
|
|
|
+ return value?.trim() ? value : '—'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function CustomerDetailPage() {
|
|
|
|
|
+ const { locale, path, copy } = usePageContext()
|
|
|
|
|
+ const { customerId } = useParams()
|
|
|
|
|
+ const [customer, setCustomer] = useState<CustomerDetailEntity | null>(null)
|
|
|
|
|
+ const pageCopy = copy.customerDetailPage
|
|
|
|
|
+
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ if (!customerId) return
|
|
|
|
|
+ getCustomerById(customerId).then(setCustomer).catch(() => setCustomer(null))
|
|
|
|
|
+ }, [customerId])
|
|
|
|
|
+
|
|
|
|
|
+ if (!customer) {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <DashboardLayout>
|
|
|
|
|
+ <Helmet>
|
|
|
|
|
+ <html lang={locale === 'ja' ? 'ja' : 'zh-CN'} />
|
|
|
|
|
+ <title>{`Aitori Stylist | ${pageCopy.title}`}</title>
|
|
|
|
|
+ <meta name="description" content={pageCopy.description} />
|
|
|
|
|
+ </Helmet>
|
|
|
|
|
+
|
|
|
|
|
+ <section className="stylist-workbench-top ipad-top-space-margin mb-2">
|
|
|
|
|
+ <div className="container">
|
|
|
|
|
+ <div className="d-flex align-items-center justify-content-between flex-wrap gap-3 mb-4">
|
|
|
|
|
+ <Link to={path('/customers')} className="btn btn-small btn-rounded btn-transparent-light-gray border border-1 border-color-dark-gray fw-700">
|
|
|
|
|
+ <i className="feather icon-feather-arrow-left me-6px"></i>{pageCopy.back}
|
|
|
|
|
+ </Link>
|
|
|
|
|
+ <Link to={path(`/customers/${customer.id}/edit`)} className="btn btn-large btn-rounded btn-base-color btn-box-shadow fw-700">
|
|
|
|
|
+ <i className="feather icon-feather-edit-3 me-8px"></i>{pageCopy.edit}
|
|
|
|
|
+ </Link>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div className="customer-detail-hero workbench-panel bg-white border-radius-8px box-shadow-extra-large p-30px">
|
|
|
|
|
+ <div className="customer-detail-profile">
|
|
|
|
|
+ <img src={customer.avatar || '/images/aitori-before-photo.png'} alt={customer.name} className="customer-detail-avatar" />
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <span className="bg-base-color d-inline-block mb-15px fw-600 text-white text-uppercase border-radius-30px ps-20px pe-20px fs-12">{pageCopy.badge}</span>
|
|
|
|
|
+ <h1 className="fw-700 text-dark-gray ls-minus-1px mb-10px">{customer.name}</h1>
|
|
|
|
|
+ <p className="fs-18 lh-30 mb-0">{getDisplayValue(customer.namePronunciation)}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="customer-next-visit">
|
|
|
|
|
+ <span className="fs-14 fw-700 text-base-color text-uppercase">{pageCopy.nextVisit.badge}</span>
|
|
|
|
|
+ <strong>{getDisplayValue(customer.recommendVisitDate)}</strong>
|
|
|
|
|
+ <p>{pageCopy.nextVisit.lead.replace('{{date}}', getDisplayValue(customer.nextFollowDate))}</p>
|
|
|
|
|
+ <button type="button" disabled className="btn btn-small btn-rounded btn-transparent-light-gray border border-1 border-color-dark-gray fw-700">
|
|
|
|
|
+ {pageCopy.nextVisit.action}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <p className="fs-14 text-medium-gray mt-10px mb-0">{pageCopy.states.undeveloped}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </section>
|
|
|
|
|
+ </DashboardLayout>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|