Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
import type { EventWizardFormData } from '@/components/events/create/consumer/types'
|
|
import { createClientId } from '@/lib/createClientId'
|
|
import type { CreatedEvent } from '@/services/events'
|
|
import type { EventFaq, EventMedia } from '@/services/eventDetail'
|
|
import { texts, format } from '@/texts'
|
|
|
|
function splitIsoToDateAndMinutes(iso: string): { date: string; minutes: number } {
|
|
const d = new Date(iso)
|
|
|
|
return {
|
|
date: d.toISOString(),
|
|
minutes: d.getHours() * 60 + d.getMinutes(),
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Maps an existing event (plus media/FAQs) into create-wizard form values
|
|
* so the host can tweak and submit a new event.
|
|
*/
|
|
export function mapEventToWizardCloneData(event: CreatedEvent, media: EventMedia[], faqs: EventFaq[]): EventWizardFormData {
|
|
const start = splitIsoToDateAndMinutes(String(event.startsAt))
|
|
const end = splitIsoToDateAndMinutes(String(event.endsAt))
|
|
|
|
return {
|
|
title: format(texts.events.cloneTitleSuffix, { title: event.title }),
|
|
slug: event.slug,
|
|
categoryId: String(event.categoryId),
|
|
shortDescription: event.shortDescription ?? '',
|
|
description: event.description ?? '',
|
|
media: media
|
|
.filter((item) => item.mediaType === 'image')
|
|
.map((item, index) => ({
|
|
id: createClientId(),
|
|
url: item.url,
|
|
isPoster: item.isPoster,
|
|
isSquarePoster: Boolean(item.isSquarePoster),
|
|
sortOrder: item.sortOrder ?? index,
|
|
})),
|
|
startDate: start.date,
|
|
startTime: start.minutes,
|
|
endDate: end.date,
|
|
endTime: end.minutes,
|
|
provinceId: String(event.provinceId),
|
|
cityId: String(event.cityId),
|
|
// Cloning always starts from the organizer's own event, so the backend
|
|
// never masks address/lat/lng here (see EventsService.applyAddressVisibility)
|
|
// -- the `?? ` fallbacks only satisfy the DTO's general nullable type.
|
|
address: event.address ?? '',
|
|
lat: event.lat ?? 35.6892,
|
|
lng: event.lng ?? 51.389,
|
|
isFree: event.isFree,
|
|
price: event.price,
|
|
capacity: event.capacity,
|
|
reservedCapacity: event.reservedCapacity ?? 0,
|
|
genderRestriction: event.genderRestriction ?? 'open',
|
|
ageRestriction: event.ageRestriction ?? 'open',
|
|
cancellationFeePercent: event.cancellationFeePercent,
|
|
isDiscoverable: event.settings.isDiscoverable,
|
|
autoCreateGroup: event.settings.autoCreateGroup,
|
|
addressVisibility: event.settings.addressVisibility,
|
|
generalArea: event.settings.generalArea ?? '',
|
|
waitlistAutoOffer: event.settings.waitlistAutoOffer,
|
|
sendReviewRequestSms: event.settings.sendReviewRequestSms ?? true,
|
|
faqs: faqs.map((faq) => ({
|
|
id: createClientId(),
|
|
question: faq.question,
|
|
answer: faq.answer,
|
|
})),
|
|
}
|
|
}
|