admin/components/events/create/cloneFromEvent.ts

73 lines
2.8 KiB
TypeScript

import type { EventWizardFormData } from '@/components/events/create/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,
cancellationFeePercent12To24Hours: event.cancellationFeePercent12To24Hours,
cancellationFeePercentMoreThan24Hours: event.cancellationFeePercentMoreThan24Hours,
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,
})),
}
}