update to use schema

This commit is contained in:
chark1es 2025-02-28 22:18:09 -08:00
parent 701854e633
commit 16addfb9d0
6 changed files with 86 additions and 35 deletions

View file

@ -41,7 +41,7 @@ const ASFundingSection: React.FC<ASFundingSectionProps> = ({ formData, onDataCha
// Handle multiple invoice files upload // Handle multiple invoice files upload
const handleMultipleInvoiceFilesChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleMultipleInvoiceFilesChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) { if (e.target.files && e.target.files.length > 0) {
const files = Array.from(e.target.files); const files = Array.from(e.target.files) as File[];
// Check file sizes // Check file sizes
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit per file const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit per file

View file

@ -6,6 +6,7 @@ import { Update } from '../../../scripts/pocketbase/Update';
import { FileManager } from '../../../scripts/pocketbase/FileManager'; import { FileManager } from '../../../scripts/pocketbase/FileManager';
import { Get } from '../../../scripts/pocketbase/Get'; import { Get } from '../../../scripts/pocketbase/Get';
import type { EventRequest } from '../../../schemas/pocketbase'; import type { EventRequest } from '../../../schemas/pocketbase';
import { EventRequestStatus } from '../../../schemas/pocketbase';
// Form sections // Form sections
import PRSection from './PRSection'; import PRSection from './PRSection';
@ -238,7 +239,7 @@ const EventRequestForm: React.FC = () => {
vendor: formData.invoiceData.vendor vendor: formData.invoiceData.vendor
}, },
// Set the initial status to "submitted" // Set the initial status to "submitted"
status: "submitted", status: EventRequestStatus.SUBMITTED,
}; };
toast.loading('Creating event request record...', { id: submittingToast }); toast.loading('Creating event request record...', { id: submittingToast });

View file

@ -3,6 +3,7 @@ import { motion } from 'framer-motion';
import type { EventRequestFormData } from './EventRequestForm'; import type { EventRequestFormData } from './EventRequestForm';
import type { InvoiceItem } from './InvoiceBuilder'; import type { InvoiceItem } from './InvoiceBuilder';
import type { EventRequest } from '../../../schemas/pocketbase'; import type { EventRequest } from '../../../schemas/pocketbase';
import { FlyerTypes, LogoOptions, EventRequestStatus } from '../../../schemas/pocketbase';
interface EventRequestFormPreviewProps { interface EventRequestFormPreviewProps {
formData?: EventRequestFormData; // Optional prop to directly pass form data formData?: EventRequestFormData; // Optional prop to directly pass form data

View file

@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import type { EventRequestFormData } from './EventRequestForm'; import type { EventRequestFormData } from './EventRequestForm';
import type { EventRequest } from '../../../schemas/pocketbase'; import type { EventRequest } from '../../../schemas/pocketbase';
import { FlyerTypes, LogoOptions } from '../../../schemas/pocketbase';
// Animation variants // Animation variants
const itemVariants = { const itemVariants = {
@ -19,24 +20,24 @@ const itemVariants = {
// Flyer type options // Flyer type options
const FLYER_TYPES = [ const FLYER_TYPES = [
{ value: 'digital_with_social', label: 'Digital flyer (with social media advertising: Facebook, Instagram, Discord)' }, { value: FlyerTypes.DIGITAL_WITH_SOCIAL, label: 'Digital flyer (with social media advertising: Facebook, Instagram, Discord)' },
{ value: 'digital_no_social', label: 'Digital flyer (with NO social media advertising)' }, { value: FlyerTypes.DIGITAL_NO_SOCIAL, label: 'Digital flyer (with NO social media advertising)' },
{ value: 'physical_with_advertising', label: 'Physical flyer (with advertising)' }, { value: FlyerTypes.PHYSICAL_WITH_ADVERTISING, label: 'Physical flyer (with advertising)' },
{ value: 'physical_no_advertising', label: 'Physical flyer (with NO advertising)' }, { value: FlyerTypes.PHYSICAL_NO_ADVERTISING, label: 'Physical flyer (with NO advertising)' },
{ value: 'newsletter', label: 'Newsletter (IEEE, ECE, IDEA)' }, { value: FlyerTypes.NEWSLETTER, label: 'Newsletter (IEEE, ECE, IDEA)' },
{ value: 'other', label: 'Other' } { value: FlyerTypes.OTHER, label: 'Other' }
]; ];
// Logo options // Logo options
const LOGO_OPTIONS = [ const LOGO_OPTIONS = [
{ value: 'IEEE', label: 'IEEE' }, { value: LogoOptions.IEEE, label: 'IEEE' },
{ value: 'AS', label: 'AS (required if funded by AS)' }, { value: LogoOptions.AS, label: 'AS (required if funded by AS)' },
{ value: 'HKN', label: 'HKN' }, { value: LogoOptions.HKN, label: 'HKN' },
{ value: 'TESC', label: 'TESC' }, { value: LogoOptions.TESC, label: 'TESC' },
{ value: 'PIB', label: 'PIB' }, { value: LogoOptions.PIB, label: 'PIB' },
{ value: 'TNT', label: 'TNT' }, { value: LogoOptions.TNT, label: 'TNT' },
{ value: 'SWE', label: 'SWE' }, { value: LogoOptions.SWE, label: 'SWE' },
{ value: 'OTHER', label: 'OTHER (please upload transparent logo files)' } { value: LogoOptions.OTHER, label: 'OTHER (please upload transparent logo files)' }
]; ];
// Format options // Format options
@ -76,7 +77,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
// Handle file upload for other logos // Handle file upload for other logos
const handleLogoFileChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleLogoFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) { if (e.target.files && e.target.files.length > 0) {
const newFiles = Array.from(e.target.files); const newFiles = Array.from(e.target.files) as File[];
setOtherLogoFiles(newFiles); setOtherLogoFiles(newFiles);
onDataChange({ other_logos: newFiles }); onDataChange({ other_logos: newFiles });
} }
@ -113,7 +114,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
</div> </div>
{/* Other flyer type input */} {/* Other flyer type input */}
{formData.flyer_type.includes('other') && ( {formData.flyer_type.includes(FlyerTypes.OTHER) && (
<div className="mt-3 pl-7"> <div className="mt-3 pl-7">
<input <input
type="text" type="text"
@ -129,9 +130,9 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
{/* Advertising start date */} {/* Advertising start date */}
{formData.flyer_type.some(type => {formData.flyer_type.some(type =>
type === 'digital_with_social' || type === FlyerTypes.DIGITAL_WITH_SOCIAL ||
type === 'physical_with_advertising' || type === FlyerTypes.PHYSICAL_WITH_ADVERTISING ||
type === 'newsletter' type === FlyerTypes.NEWSLETTER
) && ( ) && (
<motion.div variants={itemVariants} className="form-control"> <motion.div variants={itemVariants} className="form-control">
<label className="label"> <label className="label">
@ -169,7 +170,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
</motion.div> </motion.div>
{/* Logo file upload */} {/* Logo file upload */}
{formData.required_logos.includes('OTHER') && ( {formData.required_logos.includes(LogoOptions.OTHER) && (
<motion.div variants={itemVariants} className="form-control"> <motion.div variants={itemVariants} className="form-control">
<label className="label"> <label className="label">
<span className="label-text font-medium">Please share your logo files here</span> <span className="label-text font-medium">Please share your logo files here</span>

View file

@ -74,12 +74,12 @@ export interface EventRequest extends BaseRecord {
end_date_time: string; end_date_time: string;
event_description: string; event_description: string;
flyers_needed: boolean; flyers_needed: boolean;
flyer_type?: string[]; flyer_type?: string[]; // digital_with_social, digital_no_social, physical_with_advertising, physical_no_advertising, newsletter, other
other_flyer_type?: string; other_flyer_type?: string;
flyer_advertising_start_date?: string; flyer_advertising_start_date?: string;
flyer_additional_requests?: string; flyer_additional_requests?: string;
photography_needed: boolean; photography_needed: boolean;
required_logos?: string[]; required_logos?: string[]; // IEEE, AS, HKN, TESC, PIB, TNT, SWE, OTHER
other_logos?: string[]; other_logos?: string[];
advertising_format?: string; advertising_format?: string;
will_or_have_room_booking?: boolean; will_or_have_room_booking?: boolean;
@ -89,9 +89,10 @@ export interface EventRequest extends BaseRecord {
food_drinks_being_served: boolean; food_drinks_being_served: boolean;
itemized_invoice?: string; // JSON string itemized_invoice?: string; // JSON string
invoice?: string; invoice?: string;
invoice_files?: string[]; // Array of invoice file IDs
needs_graphics?: boolean; needs_graphics?: boolean;
needs_as_funding?: boolean; needs_as_funding?: boolean;
status: string; status: "submitted" | "pending" | "completed" | "declined";
requested_user?: string; requested_user?: string;
} }
@ -115,7 +116,7 @@ export interface Log extends BaseRecord {
export interface Officer extends BaseRecord { export interface Officer extends BaseRecord {
user: string; // Relation to User user: string; // Relation to User
role: string; role: string;
type: string; // e.g., "administrator" type: "administrator" | "executive" | "general" | "honorary" | "past";
} }
/** /**
@ -195,3 +196,54 @@ export const Collections = {
RECEIPTS: "receipts", RECEIPTS: "receipts",
SPONSORS: "sponsors", SPONSORS: "sponsors",
}; };
/**
* Flyer Type Options
* Constants for the flyer type options used in event requests
*/
export const FlyerTypes = {
DIGITAL_WITH_SOCIAL: "digital_with_social",
DIGITAL_NO_SOCIAL: "digital_no_social",
PHYSICAL_WITH_ADVERTISING: "physical_with_advertising",
PHYSICAL_NO_ADVERTISING: "physical_no_advertising",
NEWSLETTER: "newsletter",
OTHER: "other",
};
/**
* Logo Options
* Constants for the logo options used in event requests
*/
export const LogoOptions = {
IEEE: "IEEE",
AS: "AS",
HKN: "HKN",
TESC: "TESC",
PIB: "PIB",
TNT: "TNT",
SWE: "SWE",
OTHER: "OTHER",
};
/**
* Event Request Status Options
* Constants for the status options used in event requests
*/
export const EventRequestStatus = {
SUBMITTED: "submitted",
PENDING: "pending",
COMPLETED: "completed",
DECLINED: "declined",
};
/**
* Officer Type Options
* Constants for the officer type options
*/
export const OfficerTypes = {
ADMINISTRATOR: "administrator",
EXECUTIVE: "executive",
GENERAL: "general",
HONORARY: "honorary",
PAST: "past",
};

View file

@ -1,14 +1,10 @@
{ {
"extends": "astro/tsconfigs/strict", "extends": "astro/tsconfigs/strict",
"include": [ "include": [".astro/types.d.ts", "**/*"],
".astro/types.d.ts", "exclude": ["dist"],
"**/*"
],
"exclude": [
"dist"
],
"compilerOptions": { "compilerOptions": {
"jsx": "react-jsx", "jsx": "react-jsx",
"jsxImportSource": "react" "jsxImportSource": "react",
"esModuleInterop": true
} }
} }