Skip to content

Commit

Permalink
Merge pull request #844 from bounswe/FRONTEND-841
Browse files Browse the repository at this point in the history
Image Uploading
  • Loading branch information
alitariksahin authored Dec 15, 2024
2 parents a3ed79c + 15d928e commit a8cb2e5
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 41 deletions.
1 change: 1 addition & 0 deletions frontend/src/components/common/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export const convertQuizResponseToQuiz = (quizResponse: QuizResponse): Quiz => {
tags: quizResponse.tags,
timestamp: formatTimeAgo(quizResponse.created_at),
created_at: quizResponse.created_at,
picture: quizResponse.title_image,
level: quizResponse.level,
times_taken: quizResponse.times_taken,
},
Expand Down
72 changes: 51 additions & 21 deletions frontend/src/components/quiz/create-quiz-metadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export default function CreateQuizMetadata({
const [description, setDescription] = useState("");
const [level, setLevel] = useState("");
const [tags, setTags] = useState<string[]>([]);
const [file, setFile] = useState<File | null>(null);
const [preview, setPreview] = useState<string | null>(null);

useEffect(() => {
const tagNames = level
Expand All @@ -44,32 +46,67 @@ export default function CreateQuizMetadata({
description,
level,
tags: tagNames,
title_image: file,
});
}, [title, description, level, tags]);

const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selectedFile = e.target.files?.[0];
if (selectedFile && selectedFile.type.startsWith('image/')) {
setFile(selectedFile);
setPreview(URL.createObjectURL(selectedFile));
}
};

return (
<Card className="w-[840px] px-2 pt-2 p-4">
<div className="flex flex-row gap-4">
<div className="bg-default-100 hover:bg-default-200 p-[60px] flex justify-center items-center rounded-3xl">
<IconPlus size={24} className="text-default-500" />
</div>
<label className="relative cursor-pointer">
<div className={`bg-default-100 hover:bg-default-200 flex flex-col justify-center items-center rounded-3xl w-[240px] h-[240px] overflow-hidden ${preview ? 'p-0' : 'p-[60px]'}`}>
{preview ? (
<img
src={preview}
alt="Preview"
className="w-full h-full object-cover"
/>
) : (
<>
<IconPlus size={24} className="text-default-500" />
<span className="text-default-500 text-sm mt-2">Upload Image</span>
</>
)}
</div>
<input
type="file"
className="hidden"
onChange={handleFileChange}
accept="image/*"
/>
</label>
<div className="flex flex-col gap-4 w-full">
<div className="flex flex-row gap-4 w-full">
<Input
isRequired
label="Title"
className="w-full"
size="sm"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<Input
isRequired
label="Title"
className="w-full"
size="sm"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<Textarea
label="Description"
placeholder="Enter your description"
className="w-full"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<div className="flex flex-row gap-4">
<Select
isRequired
size="lg"
placeholder="Level*"
selectedKeys={new Set([level])}
radius="sm"
className="max-w-24"
className="w-1/2"
onSelectionChange={(keys) =>
setLevel(Array.from(keys)[0]?.toString() || "")
}
Expand All @@ -85,7 +122,7 @@ export default function CreateQuizMetadata({
selectedKeys={new Set(tags)}
selectionMode="multiple"
radius="sm"
className="max-w-36"
className="w-1/2"
onSelectionChange={(keys) =>
setTags(Array.from(keys) as string[])
}
Expand All @@ -95,13 +132,6 @@ export default function CreateQuizMetadata({
))}
</Select>
</div>
<Textarea
label="Description"
placeholder="Enter your description"
className="w-full"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
</div>
</div>
</Card>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/quiz/quiz-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export default function QuizCard({
</div>
<Divider className="mt-1.5 bg-zinc-200" />
</CardHeader>
<div className="flex flex-row justify-between items-center mb-5">
<div className="flex flex-row justify-between items-center mb-4 ml-4 mr-4">
{picture ? (
<img
src={picture}
Expand All @@ -157,6 +157,7 @@ export default function QuizCard({
height: "200px",
objectFit: "cover",
objectPosition: "center",
borderRadius: "10px",
}}
onClick={() => navigate(`/quiz/${id}/details`)}
/>
Expand Down
30 changes: 24 additions & 6 deletions frontend/src/pages/quiz-creation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,41 @@ export default function QuizCreation() {
const handleSubmit = () => {
setIsLoading(true);
const token = getToken("access");
const formData: QuizCreationModel = {
quiz: quizHeader,
questions: quizQuestions,
};
const formData = new FormData();

// Add quiz details
formData.append("title", quizHeader.title);
formData.append("description", quizHeader.description);
formData.append("level", quizHeader.level);
formData.append("tags", JSON.stringify(quizHeader.tags));

// Add title image if exists
if (quizHeader.title_image) {
formData.append("title_image", quizHeader.title_image);
}

formData.append(
`questions`,
JSON.stringify(
quizQuestions,
)
);
console.log("Form data:", formData);

axios
.post(`${BASE_URL}/quiz/create/`, formData, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
"Content-Type": "multipart/form-data",
},
})
.then((response) => {
console.log(response);
navigate("/quizzes");
})
.catch((error) => {
console.log(error);
console.error(error);
setIsLoading(false);
});
};

Expand Down
Loading

0 comments on commit a8cb2e5

Please sign in to comment.