import React, { useEffect, useState } from 'react' import { Link, useSearchParams } from 'react-router-dom' import { Helmet } from 'react-helmet-async' import { DashboardLayout } from '../../../layouts/DashboardLayout' import { listCustomers } from '../../../services/api/customers' import type { CustomerEntity } from '../../../services/api/customers' import type { SimulationTemplateOption } from '../../../services/api/contracts' import { createSimulation, listSimulationTemplates, uploadMedia, } from '../../../services/api/simulations' import { TEMPLATE_LIMIT, usePageContext, usePreviewUrl, } from '../../../shared/pageContext' export function StylistSimulationPage() { const [searchParams] = useSearchParams() const { locale, navigate, path, copy } = usePageContext() const presetCustomerId = searchParams.get('customerId') ?? '' const pageCopy = copy.simulationCreatePage const [bindCustomer, setBindCustomer] = useState(Boolean(presetCustomerId)) const [selectedCustomerId, setSelectedCustomerId] = useState(presetCustomerId) const [templateSource, setTemplateSource] = useState<'STYLIST' | 'SYSTEM'>('STYLIST') const [selectedTemplates, setSelectedTemplates] = useState([]) const [customers, setCustomers] = useState([]) const [templates, setTemplates] = useState([]) const [file, setFile] = useState(null) const [originImageUrl, setOriginImageUrl] = useState('') const [remark, setRemark] = useState('') const [uploading, setUploading] = useState(false) const [submitting, setSubmitting] = useState(false) const [error, setError] = useState('') const previewUrl = usePreviewUrl(file, originImageUrl || '/images/aitori-before-photo.png') const selectedCustomer = customers.find((item) => item.id === selectedCustomerId) || null useEffect(() => { void listCustomers().then((result) => { setCustomers(result.items) if (presetCustomerId && result.items.some((item) => item.id === presetCustomerId)) { setBindCustomer(true) setSelectedCustomerId(presetCustomerId) } }) }, [presetCustomerId]) useEffect(() => { void listSimulationTemplates({ source: templateSource, page: 1, pageSize: 12, }) .then((result) => { setTemplates(result.items) }) .catch(() => { setTemplates([]) }) }, [templateSource]) const toggleTemplate = (templateId: string) => { setSelectedTemplates((current) => { if (current.includes(templateId)) { return current.filter((item) => item !== templateId) } if (current.length >= TEMPLATE_LIMIT) { return current } return [...current, templateId] }) } const handleUpload = async (event: React.ChangeEvent) => { const nextFile = event.target.files?.[0] || null setFile(nextFile) setError('') if (!nextFile) { setOriginImageUrl('') return } setUploading(true) try { const uploaded = await uploadMedia(nextFile, 'ai-user-origin-image') setOriginImageUrl(uploaded.url) } catch (uploadError) { setOriginImageUrl('') setError( uploadError instanceof Error ? uploadError.message : pageCopy.errors.submitFailed, ) } finally { setUploading(false) } } const handleSubmit = async (event: React.FormEvent) => { event.preventDefault() if (submitting) return if (bindCustomer && !selectedCustomerId) { setError(pageCopy.errors.customerRequired) return } if (!originImageUrl) { setError(pageCopy.errors.originRequired) return } if (selectedTemplates.length === 0) { setError(pageCopy.errors.templateRequired) return } setError('') setSubmitting(true) try { const response = await createSimulation({ customerId: bindCustomer && selectedCustomerId ? selectedCustomerId : undefined, originImage: originImageUrl, templateIds: selectedTemplates, simulateRemark: remark, }) navigate(path(`/simulation/result/${response.simulationId}`)) } catch (submitError) { setError( submitError instanceof Error ? submitError.message : pageCopy.errors.submitFailed, ) } finally { setSubmitting(false) } } return ( {`Aitori Stylist | ${pageCopy.title}`}
{pageCopy.back}
{pageCopy.badge}

{pageCopy.title}

{pageCopy.lead}

1
{pageCopy.bindCustomer}

{pageCopy.bindCustomer}

{selectedCustomer?.name
2
{pageCopy.upload}

{pageCopy.upload}

3
{pageCopy.myTemplates}

{pageCopy.myTemplates}

{pageCopy.selectedCount.replace('{{count}}', String(selectedTemplates.length))}

{templates.length === 0 ? (

{pageCopy.emptyTemplates}

) : ( templates.map((template) => { const active = selectedTemplates.includes(template.id) return ( ) }) )}