fix signin signout and apply the new style
This commit is contained in:
@@ -8,6 +8,9 @@ type Props = {
|
||||
vehicleId: string
|
||||
companySlug: string
|
||||
dailyRate: number
|
||||
pickupLocations: string[]
|
||||
allowDifferentDropoff: boolean
|
||||
dropoffLocations: string[]
|
||||
}
|
||||
|
||||
const copy = {
|
||||
@@ -17,6 +20,11 @@ const copy = {
|
||||
lastName: 'Last name',
|
||||
email: 'Email',
|
||||
phone: 'Phone',
|
||||
pickupLocation: 'Pick-up location',
|
||||
returnLocation: 'Drop-off location',
|
||||
sameDropoff: 'Same drop-off',
|
||||
differentDropoff: 'Different drop-off',
|
||||
sameAsPickup: 'Return to the same location',
|
||||
startDate: 'Pick-up date',
|
||||
endDate: 'Return date',
|
||||
notes: 'Notes (optional)',
|
||||
@@ -30,6 +38,7 @@ const copy = {
|
||||
estimatedTotal: 'Estimated total',
|
||||
days: 'day(s)',
|
||||
genericError: 'Something went wrong. Please try again.',
|
||||
locationRequired: 'Please select the required pick-up and drop-off locations.',
|
||||
},
|
||||
fr: {
|
||||
title: 'Réserver ce véhicule',
|
||||
@@ -37,6 +46,11 @@ const copy = {
|
||||
lastName: 'Nom',
|
||||
email: 'E-mail',
|
||||
phone: 'Téléphone',
|
||||
pickupLocation: 'Lieu de départ',
|
||||
returnLocation: 'Lieu de retour',
|
||||
sameDropoff: 'Même retour',
|
||||
differentDropoff: 'Retour différent',
|
||||
sameAsPickup: 'Retour au même lieu',
|
||||
startDate: 'Date de départ',
|
||||
endDate: 'Date de retour',
|
||||
notes: 'Notes (optionnelles)',
|
||||
@@ -50,6 +64,7 @@ const copy = {
|
||||
estimatedTotal: 'Total estimé',
|
||||
days: 'jour(s)',
|
||||
genericError: 'Une erreur est survenue. Veuillez réessayer.',
|
||||
locationRequired: 'Veuillez sélectionner les lieux de départ et de retour requis.',
|
||||
},
|
||||
ar: {
|
||||
title: 'احجز هذه السيارة',
|
||||
@@ -57,6 +72,11 @@ const copy = {
|
||||
lastName: 'اسم العائلة',
|
||||
email: 'البريد الإلكتروني',
|
||||
phone: 'الهاتف',
|
||||
pickupLocation: 'موقع الاستلام',
|
||||
returnLocation: 'موقع الإرجاع',
|
||||
sameDropoff: 'نفس موقع الإرجاع',
|
||||
differentDropoff: 'موقع إرجاع مختلف',
|
||||
sameAsPickup: 'الإرجاع في نفس موقع الاستلام',
|
||||
startDate: 'تاريخ الاستلام',
|
||||
endDate: 'تاريخ الإرجاع',
|
||||
notes: 'ملاحظات (اختيارية)',
|
||||
@@ -70,18 +90,31 @@ const copy = {
|
||||
estimatedTotal: 'الإجمالي التقديري',
|
||||
days: 'يوم',
|
||||
genericError: 'حدث خطأ ما. يرجى المحاولة مرة أخرى.',
|
||||
locationRequired: 'يرجى اختيار مواقع الاستلام والإرجاع المطلوبة.',
|
||||
},
|
||||
} as const
|
||||
|
||||
export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props) {
|
||||
export default function BookingForm({
|
||||
vehicleId,
|
||||
companySlug,
|
||||
dailyRate,
|
||||
pickupLocations,
|
||||
allowDifferentDropoff,
|
||||
dropoffLocations,
|
||||
}: Props) {
|
||||
const { language } = useMarketplacePreferences()
|
||||
|
||||
const t = copy[language]
|
||||
const pickupOptions = Array.isArray(pickupLocations) ? pickupLocations : []
|
||||
const dropoffOptions = Array.isArray(dropoffLocations) ? dropoffLocations : []
|
||||
|
||||
const [firstName, setFirstName] = useState('')
|
||||
const [lastName, setLastName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [phone, setPhone] = useState('')
|
||||
const [pickupLocation, setPickupLocation] = useState(pickupOptions[0] ?? '')
|
||||
const [dropoffMode, setDropoffMode] = useState<'same' | 'different'>('same')
|
||||
const [returnLocation, setReturnLocation] = useState(dropoffOptions[0] ?? '')
|
||||
const [startDate, setStartDate] = useState('')
|
||||
const [endDate, setEndDate] = useState('')
|
||||
const [notes, setNotes] = useState('')
|
||||
@@ -102,6 +135,10 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
|
||||
setError(t.required)
|
||||
return
|
||||
}
|
||||
if ((pickupOptions.length > 0 && !pickupLocation) || (dropoffMode === 'different' && dropoffOptions.length > 0 && !returnLocation)) {
|
||||
setError(t.locationRequired)
|
||||
return
|
||||
}
|
||||
|
||||
const start = new Date(startDate)
|
||||
const end = new Date(endDate)
|
||||
@@ -121,6 +158,8 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
|
||||
phone: phone.trim(),
|
||||
startDate: start.toISOString(),
|
||||
endDate: end.toISOString(),
|
||||
pickupLocation: pickupLocation || undefined,
|
||||
returnLocation: dropoffMode === 'different' ? (returnLocation || undefined) : (pickupLocation || undefined),
|
||||
notes: notes.trim() || undefined,
|
||||
language,
|
||||
})
|
||||
@@ -194,6 +233,67 @@ export default function BookingForm({ vehicleId, companySlug, dailyRate }: Props
|
||||
/>
|
||||
</div>
|
||||
|
||||
{pickupOptions.length > 0 ? (
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-stone-600 dark:text-stone-400">{t.pickupLocation} <span className="text-red-500">*</span></label>
|
||||
<select
|
||||
value={pickupLocation}
|
||||
onChange={(e) => setPickupLocation(e.target.value)}
|
||||
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
|
||||
>
|
||||
{pickupOptions.map((location) => (
|
||||
<option key={location} value={location}>{location}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{allowDifferentDropoff ? (
|
||||
<div className="space-y-3 rounded-2xl border border-stone-200 bg-stone-50 p-4 dark:border-blue-800 dark:bg-[#0d1b38]">
|
||||
<div className="inline-flex rounded-full border border-stone-200 dark:border-blue-800 bg-white dark:bg-[#162038] p-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setDropoffMode('same')}
|
||||
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
|
||||
dropoffMode === 'same'
|
||||
? 'bg-stone-900 text-white dark:bg-orange-400 dark:text-stone-900'
|
||||
: 'text-stone-500 dark:text-stone-400'
|
||||
}`}
|
||||
>
|
||||
{t.sameDropoff}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setDropoffMode('different')}
|
||||
className={`rounded-full px-3 py-1.5 text-xs font-semibold transition ${
|
||||
dropoffMode === 'different'
|
||||
? 'bg-stone-900 text-white dark:bg-orange-400 dark:text-stone-900'
|
||||
: 'text-stone-500 dark:text-stone-400'
|
||||
}`}
|
||||
>
|
||||
{t.differentDropoff}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{dropoffMode === 'different' && dropoffOptions.length > 0 ? (
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-stone-600 dark:text-stone-400">{t.returnLocation} <span className="text-red-500">*</span></label>
|
||||
<select
|
||||
value={returnLocation}
|
||||
onChange={(e) => setReturnLocation(e.target.value)}
|
||||
className="w-full rounded-xl border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 outline-none focus:border-stone-400 dark:border-blue-800 dark:bg-[#162038] dark:text-stone-100 dark:focus:border-stone-500"
|
||||
>
|
||||
{dropoffOptions.map((location) => (
|
||||
<option key={location} value={location}>{location}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-stone-500 dark:text-stone-400">{pickupLocation || t.sameAsPickup}</p>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="space-y-1">
|
||||
<label className="text-xs font-medium text-stone-600 dark:text-stone-400">{t.startDate} <span className="text-red-500">*</span></label>
|
||||
|
||||
@@ -120,7 +120,7 @@ export default function MarketplaceHeader({
|
||||
</Link>
|
||||
{companyName ? (
|
||||
<Link
|
||||
href={`${dashboardUrl}/dashboard`}
|
||||
href={dashboardUrl}
|
||||
className="ml-1 flex items-center gap-1.5 rounded-full bg-orange-600 px-3 py-1 text-[12px] font-semibold text-white transition hover:bg-orange-700 dark:bg-orange-500 dark:hover:bg-orange-400 sm:ml-2 sm:gap-2 sm:px-4 sm:py-2 sm:text-sm"
|
||||
>
|
||||
<span className="inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/20 text-[10px] font-black dark:bg-[#07101e]/20">
|
||||
|
||||
@@ -88,7 +88,7 @@ export default function RenterShell({ children }: { children: React.ReactNode })
|
||||
|
||||
function signOut() {
|
||||
clearRenterSession()
|
||||
router.push('/renter/sign-in')
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
const isActive = (item: (typeof NAV_ITEMS)[number]) => {
|
||||
|
||||
@@ -25,7 +25,7 @@ function getDefaultFramePath(target: FrameId) {
|
||||
.find((c) => c.startsWith('employee_token='))
|
||||
|
||||
if (target === 'sign-in' && employeeToken) {
|
||||
return '/dashboard/dashboard'
|
||||
return '/dashboard'
|
||||
}
|
||||
|
||||
return frameConfig[target].path
|
||||
@@ -60,12 +60,30 @@ export default function WorkspaceFrame({ target }: { target: FrameId }) {
|
||||
setFramePath(getDefaultFramePath(target))
|
||||
}, [target])
|
||||
|
||||
useEffect(() => {
|
||||
if (target !== 'sign-in') return
|
||||
|
||||
const employeeToken = document.cookie
|
||||
.split(';')
|
||||
.map((c) => c.trim())
|
||||
.find((c) => c.startsWith('employee_token='))
|
||||
|
||||
if (employeeToken) {
|
||||
window.location.replace('/dashboard')
|
||||
}
|
||||
}, [target])
|
||||
|
||||
useEffect(() => {
|
||||
function handleFrameMessage(event: MessageEvent) {
|
||||
if (!event.data || typeof event.data !== 'object') return
|
||||
|
||||
const message = event.data as { type?: string; path?: string }
|
||||
|
||||
if (target === 'sign-in' && message.type === 'rentaldrivego:employee-login' && typeof message.path === 'string') {
|
||||
window.location.replace(message.path)
|
||||
return
|
||||
}
|
||||
|
||||
if ((message.type === 'rentaldrivego:embedded-path' || message.type === 'rentaldrivego:employee-login') && typeof message.path === 'string') {
|
||||
setFramePath(message.path)
|
||||
}
|
||||
@@ -73,7 +91,7 @@ export default function WorkspaceFrame({ target }: { target: FrameId }) {
|
||||
|
||||
window.addEventListener('message', handleFrameMessage)
|
||||
return () => window.removeEventListener('message', handleFrameMessage)
|
||||
}, [])
|
||||
}, [target])
|
||||
|
||||
useEffect(() => {
|
||||
const nextUrl = new URL(buildFrameUrl(config.appUrl, framePath))
|
||||
|
||||
Reference in New Issue
Block a user