Pull Request branch dev-clone to main #1

Merged
gitea merged 429 commits from dev-clone into main 2024-12-23 09:31:34 +00:00
Showing only changes of commit 91f9bc4745 - Show all commits

View File

@ -213,6 +213,10 @@ export default function AssessmentPage() {
const endIndex = startIndex + limit; const endIndex = startIndex + limit;
const paginatedQuestions = data?.data.slice(startIndex, endIndex) || []; const paginatedQuestions = data?.data.slice(startIndex, endIndex) || [];
const filteredQuestions = paginatedQuestions.filter((question) => {
return question.subAspectId === selectedSubAspectId; // Misalnya, jika `question` memiliki `subAspectId`
});
return ( return (
<Card shadow="sm" p="lg" radius="md" withBorder> <Card shadow="sm" p="lg" radius="md" withBorder>
<Stack gap="md"> <Stack gap="md">
@ -225,7 +229,7 @@ export default function AssessmentPage() {
{/* LEFT-SIDE */} {/* LEFT-SIDE */}
{/* Aspek dan Sub-Aspek */} {/* Aspek dan Sub-Aspek */}
<Flex direction="column" gap="xs" className="mr-4"> <Flex direction="column" gap="xs" className="mr-4 w-52">
<div className="space-y-4"> <div className="space-y-4">
{aspectsQuery.data?.data.map((aspect) => ( {aspectsQuery.data?.data.map((aspect) => (
<div <div
@ -251,7 +255,8 @@ export default function AssessmentPage() {
{aspect.subAspects.map((subAspect) => ( {aspect.subAspects.map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className="flex justify-between text-gray-600" className={`flex justify-between text-gray-600 cursor-pointer ${selectedSubAspectId === subAspect.id ? 'font-bold' : ''}`}
onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div>{subAspect.name}</div> <div>{subAspect.name}</div>
</div> </div>
@ -264,148 +269,148 @@ export default function AssessmentPage() {
</Flex> </Flex>
{/* Pertanyaan */} {/* Pertanyaan */}
<Stack gap="sm" style={{ flex: 1 }}> <Stack gap="sm" style={{ flex: 1 }}>
{paginatedQuestions.map((question: any, index: number) => { {filteredQuestions.length === 0 ? (
const questionId = question.questionId; <Text color="black" className="text-center p-3">
if (!questionId) return null; Pertanyaan tidak ada untuk sub-aspek yang dipilih.
</Text>
) : (
filteredQuestions.map((question: any, index: number) => {
const questionId = question.questionId;
if (!questionId) return null;
return ( return (
<Card <Card
key={questionId} key={questionId}
shadow="sm" shadow="sm"
p="lg" p="lg"
radius="md" radius="md"
withBorder withBorder
ref={(el) => (questionRefs.current[questionId] = el)} ref={(el) => (questionRefs.current[questionId] = el)}
style={{ position: "relative" }} style={{ position: "relative" }}
> >
<Stack gap="sm"> <Stack gap="sm">
<Flex <Flex justify="space-between" align="flex-start" style={{ width: "100%" }}>
justify="space-between" <Text
align="flex-start" className="font-bold"
style={{ width: "100%" }} style={{
> flexGrow: 1,
<Text wordBreak: "break-word",
className="font-bold" marginRight: "40px",
style={{ }}
flexGrow: 1, >
wordBreak: "break-word", {startIndex + index + 1}. {question.questionText}
marginRight: "40px", </Text>
}}
>
{startIndex + index + 1}. {question.questionText}
</Text>
<ActionIcon <ActionIcon
onClick={() => { onClick={() => {
setFlaggedQuestions((prevFlags) => ({ setFlaggedQuestions((prevFlags) => ({
...prevFlags, ...prevFlags,
[questionId]: !prevFlags[questionId], [questionId]: !prevFlags[questionId],
})); }));
toggleFlagMutation.mutate(questionId); toggleFlagMutation.mutate(questionId);
}} }}
title="Tandai" title="Tandai"
color={flaggedQuestions[questionId] ? "red" : "gray"} color={flaggedQuestions[questionId] ? "red" : "gray"}
> >
<TbFlag <TbFlag
size={24}
color={flaggedQuestions[questionId] ? "black" : "inherit"}
/>
</ActionIcon>
</Flex>
{question.options?.length > 0 ? (
<Radio.Group>
<div className="flex flex-col gap-4">
{question.options.map((option: any) => (
<label
key={option.optionId}
className="bg-gray-200 border rounded-lg p-4 cursor-pointer transition-transform transform hover:scale-105 shadow-md hover:shadow-lg flex items-center"
onClick={() =>
document.getElementById(option.optionId)?.click()
}
>
<Radio
id={option.optionId}
className="font-bold"
value={option.optionId}
label={option.optionText}
size="md"
radius="xl"
style={{ pointerEvents: "none" }}
onChange={() => {
submitAnswerMutation.mutate({
optionId: option.optionId,
assessmentId: assessmentId || "",
validationInformation: JSON.stringify({
info: "jfjforjfocn",
questionId: question.questionId // Tambahkan questionId dalam validationInformation
}),
});
}}
/>
</label>
))}
</div>
</Radio.Group>
) : (
<Text color="red">Tidak ada opsi untuk pertanyaan ini.</Text>
)}
<Textarea placeholder="Berikan keterangan terkait jawaban di atas" />
{/* File Upload */}
{question.needFile === true && (
<div
className={`pt-5 pb-5 pr-5 pl-2 border-2 border-dashed ${dragActive ? "bg-gray-100" : "bg-transparent"
} shadow-lg`} // Tambah shadow-lg
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
onClick={handleClick}
>
<Flex align="center" justify="space-between" gap="sm">
<TbUpload
size={24} size={24}
style={{ marginLeft: "8px", marginRight: "8px" }} color={flaggedQuestions[questionId] ? "black" : "inherit"}
/>{" "} />
{/* Tambah marginLeft */} </ActionIcon>
<div className="flex-grow text-right"> </Flex>
<Text className="font-bold">
Klik untuk unggah atau geser file disini
</Text>
<Text className="text-sm text-gray-400">
PNG, JPG, PDF
</Text>
</div>
</Flex>
<input
type="file"
ref={fileInputRef}
onChange={handleFileChange}
style={{ display: "none" }}
accept="image/png, image/jpeg, application/pdf"
/>
</div>
)}
{files.length > 0 && ( {question.options?.length > 0 ? (
<Stack gap="sm" mt="sm"> <Radio.Group>
<Text className="font-bold">File yang diunggah:</Text> <div className="flex flex-col gap-4">
{files.map((file, fileIndex) => ( {question.options.map((option: any) => (
<Group key={fileIndex} align="center"> <label
<Text>{file.name}</Text> key={option.optionId}
<CloseButton className="bg-gray-200 border rounded-lg p-4 cursor-pointer transition-transform transform hover:scale-105 shadow-md hover:shadow-lg flex items-center"
title="Hapus file" onClick={() => document.getElementById(option.optionId)?.click()}
onClick={() => handleRemoveFile(fileIndex)} >
<Radio
id={option.optionId}
className="font-bold"
value={option.optionId}
label={option.optionText}
size="md"
radius="xl"
style={{ pointerEvents: "none" }}
onChange={() => {
submitAnswerMutation.mutate({
optionId: option.optionId,
assessmentId: assessmentId || "",
validationInformation: JSON.stringify({
info: "jfjforjfocn",
questionId: question.questionId,
}),
});
}}
/>
</label>
))}
</div>
</Radio.Group>
) : (
<Text color="red">Tidak ada opsi untuk pertanyaan ini.</Text>
)}
<Textarea placeholder="Berikan keterangan terkait jawaban di atas" />
{/* File Upload */}
{question.needFile === true && (
<div
className={`pt-5 pb-5 pr-5 pl-2 border-2 border-dashed ${
dragActive ? "bg-gray-100" : "bg-transparent"
} shadow-lg`}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
onClick={handleClick}
>
<Flex align="center" justify="space-between" gap="sm">
<TbUpload
size={24}
style={{ marginLeft: "8px", marginRight: "8px" }}
/> />
</Group> <div className="flex-grow text-right">
))} <Text className="font-bold">
</Stack> Klik untuk unggah atau geser file disini
)} </Text>
</Stack> <Text className="text-sm text-gray-400">
</Card> PNG, JPG, PDF
); </Text>
})} </div>
</Flex>
<input
type="file"
ref={fileInputRef}
onChange={handleFileChange}
style={{ display: "none" }}
accept="image/png, image/jpeg, application/pdf"
/>
</div>
)}
{files.length > 0 && (
<Stack gap="sm" mt="sm">
<Text className="font-bold">File yang diunggah:</Text>
{files.map((file, fileIndex) => (
<Group key={fileIndex} align="center">
<Text>{file.name}</Text>
<CloseButton
title="Hapus file"
onClick={() => handleRemoveFile(fileIndex)}
/>
</Group>
))}
</Stack>
)}
</Stack>
</Card>
);
})
)}
</Stack> </Stack>
{/* Navigasi dan Pagination */} {/* Navigasi dan Pagination */}