'use client'; import { IVtuber } from "@/lib/vtubers"; import { useSearchParams } from 'next/navigation'; import React, { useContext, useState, useEffect } from 'react'; import { UppyContext } from 'app/uppy'; import { LoginButton, useAuth } from '@/components/auth'; import { Dashboard } from '@uppy/react'; import styles from '@/assets/styles/fp.module.css' import { projektMelodyEpoch } from "@/lib/constants"; import add from "date-fns/add"; import sub from "date-fns/sub"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCheckCircle, faPaperPlane, faXmark } from "@fortawesome/free-solid-svg-icons"; import { useForm, useFieldArray, ValidationMode } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as Yup from 'yup'; interface IUploadFormProps { vtubers: IVtuber[]; } interface IValidationResults { valid: boolean; issues: string[] | null; } interface IFormSchema extends Yup.InferType { }; const validationSchema = Yup.object().shape({ vtuber: Yup.number() .required('VTuber is required'), date: Yup.date() .typeError('Invalid date') // https://stackoverflow.com/a/72985532/1004931 .min(sub(projektMelodyEpoch, { days: 1 }), 'Date must be after February 7 2020') .max(add(new Date(), { days: 1 }), 'Date cannot be in the future') .required('Date is required'), notes: Yup.string().optional(), attribution: Yup.boolean().optional(), files: Yup.array() .of( Yup.object().shape({ key: Yup.string().required('key is required'), uploadId: Yup.string().required('uploadId is required') }), ) .min(1, 'At least one file is required'), }); export default function UploadForm({ vtubers }: IUploadFormProps) { const searchParams = useSearchParams(); const cuid = searchParams.get('cuid'); const uppy = useContext(UppyContext); const { authData } = useAuth(); const formOptions = { resolver: yupResolver(validationSchema), mode: 'onChange' as keyof ValidationMode, }; const { register, handleSubmit, formState: { errors, isValid }, setValue, watch, } = useForm(formOptions); const files = watch('files'); async function createUSC(data: IFormSchema) { const res = await fetch(`${process.env.NEXT_PUBLIC_STRAPI_URL}/api/user-submitted-contents/createFromUppy`, { method: 'POST', headers: { 'authorization': `Bearer ${authData?.accessToken}`, 'content-type': 'application/json', 'accept': 'application/json' }, body: JSON.stringify({ data: { files: data.files, attribution: data.attribution, notes: data.notes, vtuber: data.vtuber, date: data.date } }) }); if (!res.ok) { console.error('failed to fetch /api/user-submitted-contents/createFromUppy'); } } uppy.on('complete', async (result: any) => { let files = result.successful.map((f: any) => ({ key: f.s3Multipart.key, uploadId: f.s3Multipart.uploadId })); setValue('files', files); }); return ( <>

Upload VOD

Together we can archive all lewdtuber livestreams!

{(!authData?.accessToken) ? <> : (
createUSC(data))}>

Step 1

Upload the file

{errors.files &&

{errors.files.message?.toString()}

}
{/* {(!cuid) && } */}

Step 2

Tell us about the VOD

Choose the VTuber this VOD belongs to. (More VTubers will be added when storage/bandwidth funding is secured.)

{errors.vtuber &&

vtuber error

}
setDate(evt.target.value)} >

The date when the VOD was originally streamed.

{errors.date &&

{errors.date.message?.toString()}

}

If there are any issues with the VOD, put a note here. If there are no VOD issues, leave this field blank.

Step 3

Send the form

Step 1, File Upload
Step 2, Metadata
{/*

{message}

} /> */} {/* {fields.map((field, index) => (
{' '}
))} */} {/* { JSON.stringify({ touchedFields: Object.keys(touchedFields), errors: Object.keys(errors) }, null, 2) } */} {/* setError('date', { type: 'custom', message: 'custom message' }); */}
) }
) }