feat: format with prettier

This commit is contained in:
swve 2024-02-09 21:22:15 +01:00
parent 03fb09c3d6
commit a147ad6610
164 changed files with 11257 additions and 8154 deletions

View file

@ -1,166 +1,208 @@
import FormLayout, { FormField, FormLabelAndMessage, Input, Textarea } from '@components/StyledElements/Form/Form';
import { useFormik } from 'formik';
import FormLayout, {
FormField,
FormLabelAndMessage,
Input,
Textarea,
} from '@components/StyledElements/Form/Form'
import { useFormik } from 'formik'
import { AlertTriangle } from 'lucide-react'
import * as Switch from '@radix-ui/react-switch';
import * as Form from '@radix-ui/react-form';
import * as Switch from '@radix-ui/react-switch'
import * as Form from '@radix-ui/react-form'
import React from 'react'
import { useCourse, useCourseDispatch } from '../../../Contexts/CourseContext';
import ThumbnailUpdate from './ThumbnailUpdate';
import { useCourse, useCourseDispatch } from '../../../Contexts/CourseContext'
import ThumbnailUpdate from './ThumbnailUpdate'
type EditCourseStructureProps = {
orgslug: string,
course_uuid?: string,
orgslug: string
course_uuid?: string
}
const validate = (values: any) => {
const errors: any = {};
const errors: any = {}
if (!values.name) {
errors.name = 'Required';
}
if (!values.name) {
errors.name = 'Required'
}
if (values.name.length > 100) {
errors.name = 'Must be 100 characters or less';
}
if (values.name.length > 100) {
errors.name = 'Must be 100 characters or less'
}
if (!values.description) {
errors.description = 'Required'
}
if (!values.description) {
errors.description = 'Required';
if (values.description.length > 1000) {
errors.description = 'Must be 1000 characters or less'
}
}
if (!values.learnings) {
errors.learnings = 'Required'
}
if (values.description.length > 1000) {
errors.description = 'Must be 1000 characters or less';
}
if (!values.learnings) {
errors.learnings = 'Required';
}
return errors;
};
function EditCourseGeneral(props: EditCourseStructureProps) {
const [error, setError] = React.useState('');
const course = useCourse() as any;
const dispatchCourse = useCourseDispatch() as any;
const courseStructure = course.courseStructure;
const formik = useFormik({
initialValues: {
name: String(courseStructure.name),
description: String(courseStructure.description),
about: String(courseStructure.about),
learnings: String(courseStructure.learnings),
tags: String(courseStructure.tags),
public: String(courseStructure.public),
},
validate,
onSubmit: async values => {
},
enableReinitialize: true,
});
React.useEffect(() => {
// This code will run whenever form values are updated
if (formik.values !== formik.initialValues) {
dispatchCourse({ type: 'setIsNotSaved' });
const updatedCourse = {
...courseStructure,
name: formik.values.name,
description: formik.values.description,
about: formik.values.about,
learnings: formik.values.learnings,
tags: formik.values.tags,
public: formik.values.public,
}
dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse });
}
}, [course, formik.values, formik.initialValues]);
return (
<div> <div className="h-6"></div>
<div className='ml-10 mr-10 mx-auto bg-white rounded-xl shadow-sm px-6 py-5'>
{course.courseStructure && (
<div className="editcourse-form">
{error && (
<div className="flex justify-center bg-red-200 rounded-md text-red-950 space-x-2 items-center p-4 transition-all shadow-sm">
<AlertTriangle size={18} />
<div className="font-bold text-sm">{error}</div>
</div>
)}
<FormLayout onSubmit={formik.handleSubmit}>
<FormField name="name">
<FormLabelAndMessage label='Name' message={formik.errors.name} />
<Form.Control asChild>
<Input style={{ backgroundColor: "white" }} onChange={formik.handleChange} value={formik.values.name} type="text" required />
</Form.Control>
</FormField>
<FormField name="description">
<FormLabelAndMessage label='Description' message={formik.errors.description} />
<Form.Control asChild>
<Textarea style={{ backgroundColor: "white" }} onChange={formik.handleChange} value={formik.values.description} required />
</Form.Control>
</FormField>
<FormField name="about">
<FormLabelAndMessage label='About' message={formik.errors.about} />
<Form.Control asChild>
<Textarea style={{ backgroundColor: "white" }} onChange={formik.handleChange} value={formik.values.about} required />
</Form.Control>
</FormField>
<FormField name="learnings">
<FormLabelAndMessage label='Learnings' message={formik.errors.learnings} />
<Form.Control asChild>
<Textarea style={{ backgroundColor: "white" }} onChange={formik.handleChange} value={formik.values.learnings} required />
</Form.Control>
</FormField>
<FormField name="tags">
<FormLabelAndMessage label='Tags' message={formik.errors.tags} />
<Form.Control asChild>
<Textarea style={{ backgroundColor: "white" }} onChange={formik.handleChange} value={formik.values.tags} required />
</Form.Control>
</FormField>
<FormField name="thumbnail">
<FormLabelAndMessage label='Thumbnail' />
<Form.Control asChild>
<ThumbnailUpdate />
</Form.Control>
</FormField>
<FormField className="flex items-center h-10" name="public">
<div className='flex my-auto items-center'>
<label className="text-black text-[15px] leading-none pr-[15px]" htmlFor="public-course">
Public Course
</label>
<Switch.Root
className="w-[42px] h-[25px] bg-neutral-200 rounded-full relative data-[state=checked]:bg-neutral-500 outline-none cursor-default"
id="public-course"
onCheckedChange={checked => formik.setFieldValue('public', checked)}
checked={formik.values.public === 'true'}
>
<Switch.Thumb className="block w-[21px] h-[21px] bg-white rounded-full shadow-[0_2px_2px] shadow-neutral-300 transition-transform duration-100 translate-x-0.5 will-change-transform data-[state=checked]:translate-x-[19px]" />
</Switch.Root>
</div>
</FormField>
</FormLayout>
</div>
)}
</div>
</div>
)
return errors
}
export default EditCourseGeneral
function EditCourseGeneral(props: EditCourseStructureProps) {
const [error, setError] = React.useState('')
const course = useCourse() as any
const dispatchCourse = useCourseDispatch() as any
const courseStructure = course.courseStructure
const formik = useFormik({
initialValues: {
name: String(courseStructure.name),
description: String(courseStructure.description),
about: String(courseStructure.about),
learnings: String(courseStructure.learnings),
tags: String(courseStructure.tags),
public: String(courseStructure.public),
},
validate,
onSubmit: async (values) => {},
enableReinitialize: true,
})
React.useEffect(() => {
// This code will run whenever form values are updated
if (formik.values !== formik.initialValues) {
dispatchCourse({ type: 'setIsNotSaved' })
const updatedCourse = {
...courseStructure,
name: formik.values.name,
description: formik.values.description,
about: formik.values.about,
learnings: formik.values.learnings,
tags: formik.values.tags,
public: formik.values.public,
}
dispatchCourse({ type: 'setCourseStructure', payload: updatedCourse })
}
}, [course, formik.values, formik.initialValues])
return (
<div>
{' '}
<div className="h-6"></div>
<div className="ml-10 mr-10 mx-auto bg-white rounded-xl shadow-sm px-6 py-5">
{course.courseStructure && (
<div className="editcourse-form">
{error && (
<div className="flex justify-center bg-red-200 rounded-md text-red-950 space-x-2 items-center p-4 transition-all shadow-sm">
<AlertTriangle size={18} />
<div className="font-bold text-sm">{error}</div>
</div>
)}
<FormLayout onSubmit={formik.handleSubmit}>
<FormField name="name">
<FormLabelAndMessage
label="Name"
message={formik.errors.name}
/>
<Form.Control asChild>
<Input
style={{ backgroundColor: 'white' }}
onChange={formik.handleChange}
value={formik.values.name}
type="text"
required
/>
</Form.Control>
</FormField>
<FormField name="description">
<FormLabelAndMessage
label="Description"
message={formik.errors.description}
/>
<Form.Control asChild>
<Textarea
style={{ backgroundColor: 'white' }}
onChange={formik.handleChange}
value={formik.values.description}
required
/>
</Form.Control>
</FormField>
<FormField name="about">
<FormLabelAndMessage
label="About"
message={formik.errors.about}
/>
<Form.Control asChild>
<Textarea
style={{ backgroundColor: 'white' }}
onChange={formik.handleChange}
value={formik.values.about}
required
/>
</Form.Control>
</FormField>
<FormField name="learnings">
<FormLabelAndMessage
label="Learnings"
message={formik.errors.learnings}
/>
<Form.Control asChild>
<Textarea
style={{ backgroundColor: 'white' }}
onChange={formik.handleChange}
value={formik.values.learnings}
required
/>
</Form.Control>
</FormField>
<FormField name="tags">
<FormLabelAndMessage
label="Tags"
message={formik.errors.tags}
/>
<Form.Control asChild>
<Textarea
style={{ backgroundColor: 'white' }}
onChange={formik.handleChange}
value={formik.values.tags}
required
/>
</Form.Control>
</FormField>
<FormField name="thumbnail">
<FormLabelAndMessage label="Thumbnail" />
<Form.Control asChild>
<ThumbnailUpdate />
</Form.Control>
</FormField>
<FormField className="flex items-center h-10" name="public">
<div className="flex my-auto items-center">
<label
className="text-black text-[15px] leading-none pr-[15px]"
htmlFor="public-course"
>
Public Course
</label>
<Switch.Root
className="w-[42px] h-[25px] bg-neutral-200 rounded-full relative data-[state=checked]:bg-neutral-500 outline-none cursor-default"
id="public-course"
onCheckedChange={(checked) =>
formik.setFieldValue('public', checked)
}
checked={formik.values.public === 'true'}
>
<Switch.Thumb className="block w-[21px] h-[21px] bg-white rounded-full shadow-[0_2px_2px] shadow-neutral-300 transition-transform duration-100 translate-x-0.5 will-change-transform data-[state=checked]:translate-x-[19px]" />
</Switch.Root>
</div>
</FormField>
</FormLayout>
</div>
)}
</div>
</div>
)
}
export default EditCourseGeneral

View file

@ -1,79 +1,100 @@
import { useCourse } from '@components/Contexts/CourseContext';
import { useOrg } from '@components/Contexts/OrgContext';
import { getAPIUrl } from '@services/config/config';
import { updateCourseThumbnail } from '@services/courses/courses';
import { getCourseThumbnailMediaDirectory } from '@services/media/media';
import { ArrowBigUpDash, UploadCloud } from 'lucide-react';
import { useCourse } from '@components/Contexts/CourseContext'
import { useOrg } from '@components/Contexts/OrgContext'
import { getAPIUrl } from '@services/config/config'
import { updateCourseThumbnail } from '@services/courses/courses'
import { getCourseThumbnailMediaDirectory } from '@services/media/media'
import { ArrowBigUpDash, UploadCloud } from 'lucide-react'
import React from 'react'
import { mutate } from 'swr';
import { mutate } from 'swr'
function ThumbnailUpdate() {
const course = useCourse() as any;
const org = useOrg() as any;
const [localThumbnail, setLocalThumbnail] = React.useState(null) as any;
const [isLoading, setIsLoading] = React.useState(false) as any;
const [error, setError] = React.useState('') as any;
const course = useCourse() as any
const org = useOrg() as any
const [localThumbnail, setLocalThumbnail] = React.useState(null) as any
const [isLoading, setIsLoading] = React.useState(false) as any
const [error, setError] = React.useState('') as any
const handleFileChange = async (event: any) => {
const file = event.target.files[0];
setLocalThumbnail(file);
setIsLoading(true);
const res = await updateCourseThumbnail(course.courseStructure.course_uuid, file)
mutate(`${getAPIUrl()}courses/${course.courseStructure.course_uuid}/meta`);
// wait for 1 second to show loading animation
await new Promise(r => setTimeout(r, 1500));
if (res.success === false) {
setError(res.HTTPmessage);
} else {
setIsLoading(false);
setError('');
}
};
return (
<div className='w-auto bg-gray-50 rounded-xl outline outline-1 outline-gray-200 h-[200px] shadow'>
<div className='flex flex-col justify-center items-center h-full'>
<div className='flex flex-col justify-center items-center'>
<div className='flex flex-col justify-center items-center'>
{error && (
<div className="flex justify-center bg-red-200 rounded-md text-red-950 space-x-2 items-center p-2 transition-all shadow-sm">
<div className="text-sm font-semibold">{error}</div>
</div>
)}
{localThumbnail ? (
<img src={URL.createObjectURL(localThumbnail)} className={`${isLoading ? 'animate-pulse' : ''} shadow w-[200px] h-[100px] rounded-md`} />
) : (
<img src={`${getCourseThumbnailMediaDirectory(org?.org_uuid, course.courseStructure.course_uuid, course.courseStructure.thumbnail_image)}`} className='shadow w-[200px] h-[100px] rounded-md' />
)}
</div>
{isLoading ? (<div className='flex justify-center items-center'>
<input type="file" id="fileInput" style={{ display: 'none' }} onChange={handleFileChange} />
<div
className='font-bold animate-pulse antialiased items-center bg-green-200 text-gray text-sm rounded-md px-4 py-2 mt-4 flex'
>
<ArrowBigUpDash size={16} className='mr-2' />
<span>Uploading</span>
</div>
</div>) : (
<div className='flex justify-center items-center'>
<input type="file" id="fileInput" style={{ display: 'none' }} onChange={handleFileChange} />
<button
className='font-bold antialiased items-center text-gray text-sm rounded-md px-4 mt-6 flex'
onClick={() => document.getElementById('fileInput')?.click()}
>
<UploadCloud size={16} className='mr-2' />
<span>Change Thumbnail</span>
</button>
</div>
)}
</div>
</div>
</div>
const handleFileChange = async (event: any) => {
const file = event.target.files[0]
setLocalThumbnail(file)
setIsLoading(true)
const res = await updateCourseThumbnail(
course.courseStructure.course_uuid,
file
)
mutate(`${getAPIUrl()}courses/${course.courseStructure.course_uuid}/meta`)
// wait for 1 second to show loading animation
await new Promise((r) => setTimeout(r, 1500))
if (res.success === false) {
setError(res.HTTPmessage)
} else {
setIsLoading(false)
setError('')
}
}
return (
<div className="w-auto bg-gray-50 rounded-xl outline outline-1 outline-gray-200 h-[200px] shadow">
<div className="flex flex-col justify-center items-center h-full">
<div className="flex flex-col justify-center items-center">
<div className="flex flex-col justify-center items-center">
{error && (
<div className="flex justify-center bg-red-200 rounded-md text-red-950 space-x-2 items-center p-2 transition-all shadow-sm">
<div className="text-sm font-semibold">{error}</div>
</div>
)}
{localThumbnail ? (
<img
src={URL.createObjectURL(localThumbnail)}
className={`${
isLoading ? 'animate-pulse' : ''
} shadow w-[200px] h-[100px] rounded-md`}
/>
) : (
<img
src={`${getCourseThumbnailMediaDirectory(
org?.org_uuid,
course.courseStructure.course_uuid,
course.courseStructure.thumbnail_image
)}`}
className="shadow w-[200px] h-[100px] rounded-md"
/>
)}
</div>
{isLoading ? (
<div className="flex justify-center items-center">
<input
type="file"
id="fileInput"
style={{ display: 'none' }}
onChange={handleFileChange}
/>
<div className="font-bold animate-pulse antialiased items-center bg-green-200 text-gray text-sm rounded-md px-4 py-2 mt-4 flex">
<ArrowBigUpDash size={16} className="mr-2" />
<span>Uploading</span>
</div>
</div>
) : (
<div className="flex justify-center items-center">
<input
type="file"
id="fileInput"
style={{ display: 'none' }}
onChange={handleFileChange}
/>
<button
className="font-bold antialiased items-center text-gray text-sm rounded-md px-4 mt-6 flex"
onClick={() => document.getElementById('fileInput')?.click()}
>
<UploadCloud size={16} className="mr-2" />
<span>Change Thumbnail</span>
</button>
</div>
)}
</div>
</div>
</div>
)
}
export default ThumbnailUpdate
export default ThumbnailUpdate