Added title in about us and updated apis
|
@ -0,0 +1,29 @@
|
|||
"""add title in aboutUs
|
||||
|
||||
Revision ID: 94afd163eba3
|
||||
Revises: 8e38378fd2f3
|
||||
Create Date: 2024-10-05 10:26:21.093141
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel.sql.sqltypes
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '94afd163eba3'
|
||||
down_revision = '8e38378fd2f3'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('aboutus', sa.Column('title', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('aboutus', 'title')
|
||||
# ### end Alembic commands ###
|
|
@ -24,6 +24,7 @@ async def create_aboutUs(
|
|||
session: SessionDep,
|
||||
current_user: CurrentUser,
|
||||
description: str = Form(),
|
||||
title: str = Form(),
|
||||
image: Annotated[UploadFile, File()],
|
||||
index: int = Form()
|
||||
) -> Any:
|
||||
|
@ -33,7 +34,7 @@ async def create_aboutUs(
|
|||
validate_file_size_type(image)
|
||||
imageUrl = await save_picture(file=image, folderName="tmp")
|
||||
# aboutus_in.image = imageUrl
|
||||
aboutUs_in = AboutUsCreate(description=description, image=imageUrl, index=index)
|
||||
aboutUs_in = AboutUsCreate(description=description, image=imageUrl, index=index ,title=title)
|
||||
aboutUs = AboutUs.from_orm(aboutUs_in)
|
||||
session.add(aboutUs)
|
||||
session.commit()
|
||||
|
@ -49,6 +50,7 @@ async def edit_aboutUs(
|
|||
id: uuid.UUID,
|
||||
description: str = Form(),
|
||||
image: Annotated[UploadFile, File()] = None,
|
||||
title: str = Form(),
|
||||
index: int = Form()
|
||||
) -> Any:
|
||||
aboutUs = session.get(AboutUs, id)
|
||||
|
@ -57,9 +59,9 @@ async def edit_aboutUs(
|
|||
validate_file_size_type(image)
|
||||
imageUrl = await save_picture(file=image, folderName="tmp")
|
||||
await del_picture(aboutUs.image)
|
||||
aboutUs_in = AboutsUpdate(description=description, image=imageUrl, index=index)
|
||||
aboutUs_in = AboutsUpdate(description=description, image=imageUrl, index=index, title=title)
|
||||
else :
|
||||
aboutUs_in = AboutsUpdate(description=description, image=aboutUs.image, index=index)
|
||||
aboutUs_in = AboutsUpdate(description=description, image=aboutUs.image, index=index, title=title)
|
||||
|
||||
update_dict = aboutUs_in.model_dump(exclude_unset=True)
|
||||
aboutUs.sqlmodel_update(update_dict)
|
||||
|
|
|
@ -26,7 +26,7 @@ if settings.BACKEND_CORS_ORIGINS:
|
|||
CORSMiddleware,
|
||||
allow_origins=[
|
||||
str(origin).strip("/") for origin in settings.BACKEND_CORS_ORIGINS
|
||||
] + ["http://localhost:3000"],
|
||||
] + ["http://localhost:3000"]+["http://localhost:5173"]+["http://localhost:5173/aboutUs"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
|
|
|
@ -166,6 +166,7 @@ class Setting(SettingBase, table=True):
|
|||
class AboutUsBase(SQLModel):
|
||||
description: str = Field(max_length=1024)
|
||||
image:str | None = Field(default=None, max_length=255)
|
||||
title: str = Field(max_length=255)
|
||||
index: int
|
||||
|
||||
class AboutUsCreate(AboutUsBase):
|
||||
|
@ -209,6 +210,8 @@ class CoursePublic(CourseBase):
|
|||
id: uuid.UUID
|
||||
title: str
|
||||
images: list["Image"]
|
||||
info_images: list["Info_Image"]
|
||||
schedule: list["Schedule"]
|
||||
created_at: datetime
|
||||
|
||||
class CoursesPublic(SQLModel):
|
||||
|
|
After Width: | Height: | Size: 632 KiB |
Before Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 632 KiB |
Before Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 632 KiB |
After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 632 KiB |
|
@ -150,6 +150,7 @@ export type AboutUssPublic = {
|
|||
export type AboutUsPublic = {
|
||||
index: number,
|
||||
description: string,
|
||||
title: string,
|
||||
image: string,
|
||||
id: string
|
||||
}
|
||||
|
@ -157,12 +158,14 @@ export type AboutUsPublic = {
|
|||
export type AboutUsCreate = {
|
||||
index: number,
|
||||
description: string,
|
||||
title: string,
|
||||
image: File,
|
||||
}
|
||||
|
||||
export type AboutUsUpdate = {
|
||||
index: number,
|
||||
description: string,
|
||||
title: string,
|
||||
image?: File | undefined | null,
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ const AddAboutUs = ({ isOpen, onClose }: AddAboutUsProps) => {
|
|||
}
|
||||
mutation.mutate(data)
|
||||
console.log(data)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,6 +152,20 @@ const AddAboutUs = ({ isOpen, onClose }: AddAboutUsProps) => {
|
|||
<ModalCloseButton />
|
||||
|
||||
<ModalBody pb={30}>
|
||||
<FormControl isRequired isInvalid={!!errors.title}>
|
||||
<FormLabel htmlFor="title">Title</FormLabel>
|
||||
<Input
|
||||
id="title"
|
||||
{...register("title", {
|
||||
required: "Title is required.",
|
||||
})}
|
||||
placeholder="Title"
|
||||
type="text"
|
||||
/>
|
||||
{errors.title && (
|
||||
<FormErrorMessage>{errors.title.message}</FormErrorMessage>
|
||||
)}
|
||||
</FormControl>
|
||||
<FormControl isRequired isInvalid={!!errors.description}>
|
||||
<Editor
|
||||
editorState={editorState}
|
||||
|
@ -186,7 +200,7 @@ const AddAboutUs = ({ isOpen, onClose }: AddAboutUsProps) => {
|
|||
<NumberDecrementStepper />
|
||||
</NumberInputStepper>
|
||||
</NumberInput>
|
||||
|
||||
|
||||
{errors.index && (
|
||||
<FormErrorMessage>{errors.index.message}</FormErrorMessage>
|
||||
)}
|
||||
|
@ -195,7 +209,7 @@ const AddAboutUs = ({ isOpen, onClose }: AddAboutUsProps) => {
|
|||
<FormControl isInvalid={!!errors.image} isRequired>
|
||||
<FormLabel>{'Image Upload'}</FormLabel>
|
||||
|
||||
|
||||
|
||||
<input type="file" {...register("image", {
|
||||
required: "index is required.",
|
||||
})} />
|
||||
|
|
|
@ -89,6 +89,7 @@ const EditAboutUs = ({ aboutUs, isOpen, onClose }: EditAboutUsProps) => {
|
|||
criteriaMode: "all",
|
||||
defaultValues: {
|
||||
index: aboutUs.index,
|
||||
title: aboutUs.title,
|
||||
description: aboutUs.description,
|
||||
image: undefined,
|
||||
},
|
||||
|
@ -167,6 +168,20 @@ const EditAboutUs = ({ aboutUs, isOpen, onClose }: EditAboutUsProps) => {
|
|||
<Box boxSize='auto'>
|
||||
<Image src={url + "/" + aboutUs.image} />
|
||||
</Box>
|
||||
<FormControl isRequired isInvalid={!!errors.title}>
|
||||
<FormLabel htmlFor="title">Title</FormLabel>
|
||||
<Input
|
||||
id="title"
|
||||
{...register("title", {
|
||||
required: "Title is required.",
|
||||
})}
|
||||
placeholder="Title"
|
||||
type="text"
|
||||
/>
|
||||
{errors.title && (
|
||||
<FormErrorMessage>{errors.title.message}</FormErrorMessage>
|
||||
)}
|
||||
</FormControl>
|
||||
<FormControl isRequired isInvalid={!!errors.description}>
|
||||
<Editor
|
||||
editorState={editorState}
|
||||
|
|
|
@ -36,7 +36,7 @@ import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
|
|||
const CourseDetails = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const courseDetails = queryClient.getQueryData(['course']) as CourseDetailsPublic | undefined;
|
||||
|
||||
|
||||
const toolbar = {
|
||||
options: ['inline', 'blockType', 'fontSize', 'list', 'textAlign', 'history', 'embedded', 'emoji', 'image'],
|
||||
inline: { inDropdown: true },
|
||||
|
@ -78,9 +78,14 @@ const CourseDetails = () => {
|
|||
})
|
||||
|
||||
useEffect(() => {
|
||||
reset({}, { keepDirty: true });
|
||||
if (courseDetails) {
|
||||
setValue('title', courseDetails.title);
|
||||
setValue('sort_description', courseDetails.sort_description);
|
||||
setValue('title', courseDetails.title, { shouldDirty: true });
|
||||
setValue('sort_description', courseDetails.sort_description, { shouldDirty: true });
|
||||
setValue('long_description', courseDetails.long_description, { shouldDirty: true });
|
||||
setValue('remark', courseDetails.remark, { shouldDirty: true });
|
||||
setValue('information', courseDetails.information, { shouldDirty: true });
|
||||
setValue('contant', courseDetails.contant, { shouldDirty: true });
|
||||
// Update other form fields as needed
|
||||
}
|
||||
if (courseDetails?.long_description) {
|
||||
|
@ -89,7 +94,7 @@ const CourseDetails = () => {
|
|||
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
|
||||
const editorState = EditorState.createWithContent(contentState);
|
||||
setLongDescriptionEditorState(editorState);
|
||||
setValue('long_description', longDescription);
|
||||
// setValue('long_description', courseDetails.long_description);
|
||||
}
|
||||
}
|
||||
if (courseDetails?.remark) {
|
||||
|
@ -98,7 +103,7 @@ const CourseDetails = () => {
|
|||
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
|
||||
const editorState = EditorState.createWithContent(contentState);
|
||||
setRemarksEditorState(editorState);
|
||||
setValue('remark', remarks);
|
||||
//setValue('remark', courseDetails.remark);
|
||||
}
|
||||
}
|
||||
if (courseDetails?.information) {
|
||||
|
@ -107,7 +112,7 @@ const CourseDetails = () => {
|
|||
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
|
||||
const editorState = EditorState.createWithContent(contentState);
|
||||
setInfoEditorState(editorState);
|
||||
setValue('information', info);
|
||||
//setValue('information', courseDetails.information);
|
||||
}
|
||||
}
|
||||
if (courseDetails?.contant) {
|
||||
|
@ -116,11 +121,10 @@ const CourseDetails = () => {
|
|||
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
|
||||
const editorState = EditorState.createWithContent(contentState);
|
||||
setContentEditorState(editorState);
|
||||
setValue('contant', contents);
|
||||
//setValue('contant', courseDetails.contant);
|
||||
}
|
||||
}
|
||||
}, [courseDetails]);
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: (data: CourseCreate) =>
|
||||
CoursesService.updateCourse({ id: courseDetails?.id ?? '', requestBody: data }),
|
||||
|
|
|
@ -51,7 +51,7 @@ function EditCourse() {
|
|||
return (
|
||||
<Container maxW="full">
|
||||
<Heading size="lg" textAlign={{ base: "center", md: "left" }} py={12}>
|
||||
User Settings
|
||||
Courses
|
||||
</Heading>
|
||||
<Tabs variant="enclosed">
|
||||
<TabList>
|
||||
|
|
|
@ -76,6 +76,7 @@ function AboutUsTable() {
|
|||
<Thead>
|
||||
<Tr>
|
||||
<Th>ID</Th>
|
||||
<Th>Title</Th>
|
||||
<Th>Description</Th>
|
||||
<Th>Image</Th>
|
||||
<Th>Index</Th>
|
||||
|
@ -97,6 +98,12 @@ function AboutUsTable() {
|
|||
{aboutUs?.data.map((aboutUs) => (
|
||||
<Tr key={aboutUs.id} opacity={isPlaceholderData ? 0.5 : 1}>
|
||||
<Td isTruncated maxWidth="50">{aboutUs.id}</Td>
|
||||
<Td
|
||||
whiteSpace="pre-line"
|
||||
maxWidth="350px"
|
||||
>
|
||||
{parse(aboutUs.title)}
|
||||
</Td>
|
||||
|
||||
<Td
|
||||
whiteSpace="pre-line"
|
||||
|
|