booking form validation and data types

This commit is contained in:
Asya Vee
2025-08-26 18:06:44 +04:00
parent 07ff37f038
commit 47baf8dfe2
11 changed files with 661 additions and 279 deletions

View File

@@ -1,79 +1,186 @@
// types/booking.ts
export interface BookingType {
id: string;
name: string;
display_name: string;
requires_payment: boolean;
default_duration: number; // in minutes
description?: string;
resources: string; // relation to resources collection
created: string;
updated: string;
// Base types for PocketBase records
export interface BaseRecord {
id: string;
created: string;
updated: string;
}
export interface Resource {
id: string;
type: 'wheel' | 'workstation';
capacity: number;
is_active: boolean;
created: string;
updated: string;
// Resource entity
export interface Resource extends BaseRecord {
name: string;
type: 'wheel' | 'workstation';
capacity: number;
is_active: boolean;
}
export interface TimeSlot {
id: string;
booking_types: string[]; // relation to booking types
start_time: string;
end_time: string;
is_reccuring: boolean;
max_capacity: number;
is_active: boolean;
recurrence_pattern?: {
type: string;
days: number[];
end_date: string;
};
created: string;
updated: string;
// Booking Type entity
export interface BookingType extends BaseRecord {
name: string;
display_name: string;
description?: string;
requires_payment?: boolean;
base_duration: number; // minutes, min 30
min_duration: number;
price_per_person: number;
resources: string; // relation to Resource
min_capacity: number;
max_capacity: number;
is_active: boolean;
}
export interface Booking {
id: string;
booking_type: string; // relation to booking type
customer_name: string;
customer_email: string;
internal_notes?: string;
start_time: string;
end_time: string;
participants_count: number;
status: 'confirmed' | 'cancelled' | 'completed';
payment_status: 'not_required' | 'paid' | 'refunded' | 'partially_refunded' | 'pending';
payment_required: boolean;
cancellation_token: string;
created: string;
updated: string;
// Time Slot entity
export interface TimeSlot extends BaseRecord {
booking_types: string[]; // relation to BookingType (many-to-many)
start_time: string;
end_time: string;
is_active: boolean;
is_reccuring?: boolean;
recurrence_pattern?: RecurrencePattern;
max_capacity: number;
}
// Recurrence pattern structure
export interface RecurrencePattern {
type: 'daily' | 'weekly' | 'monthly';
interval: number;
days_of_week?: number[]; // 0-6, Sunday = 0
end_date?: string;
occurrences?: number;
}
// Booking entity
export interface Booking extends BaseRecord {
booking_type: string; // relation to BookingType
customer_name: string;
customer_email: string;
internal_notes?: string;
start_time: string;
end_time: string;
participants_count: number;
status: 'confirmed' | 'cancelled' | 'completed';
payment_status: 'not_required' | 'paid' | 'refunded' | 'partially_refunded' | 'pending';
payment_required: boolean;
cancellation_token: string;
use_subscription?: string; // relation to subscription (future feature)
}
// Frontend form types
export interface BookingFormData {
bookingTypeId: string;
customerName: string;
customerEmail: string;
participantsCount: number;
startTime: Date;
endTime: Date;
bookingTypeId: string;
customerName: string;
customerEmail: string;
startTime: string;
endTime: string;
participantsCount: number;
internalNotes?: string;
}
// For the booking flow state
export interface BookingFlowState {
step: 'booking-type' | 'date-time' | 'customer-details' | 'confirmation';
selectedBookingType?: BookingType;
selectedDate?: Date;
selectedTimeSlot?: string; // time slot ID or time string
customerDetails?: {
name: string;
email: string;
participantsCount: number;
notes?: string;
};
}
// API response types
export interface BookingResponse {
success: boolean;
booking?: Booking;
error?: string;
cancellationUrl?: string;
}
export interface AvailabilityResponse {
success: boolean;
availableSlots?: TimeSlot[];
error?: string;
}
// Expanded types with relations
export interface BookingWithRelations extends Omit<Booking, 'booking_type'> {
expand?: {
booking_type?: BookingType;
};
}
export interface BookingTypeWithRelations extends Omit<BookingType, 'resources'> {
expand?: {
resources?: Resource;
};
}
export interface TimeSlotWithRelations extends Omit<TimeSlot, 'booking_types'> {
expand?: {
booking_types?: BookingType[];
};
}
// Utility types for API operations
export interface CreateBookingData {
booking_type: string;
customer_name: string;
customer_email: string;
start_time: string;
end_time: string;
participants_count: number;
internal_notes?: string;
status: 'confirmed';
payment_status: 'not_required' | 'pending';
payment_required: boolean;
}
export interface UpdateBookingData {
status?: 'confirmed' | 'cancelled' | 'completed';
payment_status?: 'not_required' | 'paid' | 'refunded' | 'partially_refunded' | 'pending';
internal_notes?: string;
}
// Filter and query types
export interface BookingFilters {
status?: string;
payment_status?: string;
booking_type?: string;
date_from?: string;
date_to?: string;
customer_email?: string;
}
export interface TimeSlotFilters {
booking_type?: string;
date_from?: string;
date_to?: string;
is_active?: boolean;
}
// Error types
export interface BookingError {
code: string;
message: string;
field?: string;
}
// Validation types
export interface BookingValidation {
isValid: boolean;
errors: BookingError[];
}
// Constants
export const BOOKING_TYPES = {
WHEEL_RENTAL: 'wheel_rental',
HAND_BUILDING: 'hand_building_coworking',
PERSONAL_WORKSHOP: 'personal_workshop',
GROUP_WORKSHOP: 'group_workshop',
} as const;
export const BOOKING_STATUS = {
CONFIRMED: 'confirmed',
CANCELLED: 'cancelled',
COMPLETED: 'completed',
} as const;
export const PAYMENT_STATUS = {
NOT_REQUIRED: 'not_required',
PAID: 'paid',
REFUNDED: 'refunded',
PARTIALLY_REFUNDED: 'partially_refunded',
PENDING: 'pending',
} as const;
export const RESOURCE_TYPES = {
WHEEL: 'wheel',
WORKSTATION: 'workstation',
} as const;