From 7901fc3f828755cd386931747a798d19018eebcd Mon Sep 17 00:00:00 2001 From: asepharyana Date: Wed, 5 Aug 2026 23:18:51 +0700 Subject: [PATCH] feat(dimentorin): feedback mentor 2-step modal (Figma Modals-Feedback 1 & 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Halaman yang belum ada di FE: feedback mentor setelah sesi selesai. Figma punya 'Modals - Feedback 1' (rating 1-5 + 2 pertanyaan pilihan) dan 'Modals - Feedback 2' (3 textarea: suka/tingkatkan/testimoni). BE sudah punya POST /dimentorin/sessions/{id}/feedback/create. - BARU mentoring/_components/feedback-modal.tsx: modal 2 step (rating bintang + kebermanfaatan + rekomendasi → textarea suka/tingkatkan/testimoni), validasi step (Lanjut disabled sampai rating+opsi dipilih), submit gabung jadi feedback text + rating, reset state tiap buka - my-sessions: tombol '⭐ Beri Feedback' muncul untuk sesi status completed; modal ter-integrasi; invalidate my-sessions + mentor-stats setelah submit - Verifikasi end-to-end via browser: tombol muncul, modal step 1 → rating 5 + opsi → step 2 → isi textarea → Kirim → POST 200 feedback+rating tersimpan di DB (sesi Status Test di-set completed utk test lalu di-reset) --- .../mentoring/_components/feedback-modal.tsx | 256 ++++++++++++++++++ .../(public)/mentoring/my-sessions/page.tsx | 36 ++- 2 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 apps/dimentorin/src/app/(public)/mentoring/_components/feedback-modal.tsx diff --git a/apps/dimentorin/src/app/(public)/mentoring/_components/feedback-modal.tsx b/apps/dimentorin/src/app/(public)/mentoring/_components/feedback-modal.tsx new file mode 100644 index 0000000..b90e419 --- /dev/null +++ b/apps/dimentorin/src/app/(public)/mentoring/_components/feedback-modal.tsx @@ -0,0 +1,256 @@ +import { FC, ReactElement, useEffect, useState } from 'react'; +import { Button } from '@imphnen-frontend-service/ui/atoms'; +import { Modal } from '@imphnen-frontend-service/ui/molecules'; +import { cn, Show } from '@imphnen-frontend-service/utils'; +import { usePostSessionFeedback } from '@imphnen-frontend-service/service'; +import { StarFilled, StarOutlined } from '@ant-design/icons'; +import { toast } from 'sonner'; + +const RATING_LABELS: Record = { + 1: 'Sangat Tidak Puas', + 2: 'Tidak Puas', + 3: 'Cukup Puas', + 4: 'Puas', + 5: 'Sangat Puas', +}; + +type FeedbackModalProps = { + open: boolean; + sessionId: string; + mentorName?: string | null; + onClose: () => void; + onSuccess: () => void; +}; + +const RATING_QUESTIONS: { question: string; options: string[] }[] = [ + { + question: 'Seberapa membantu jawaban mentor untuk kebutuhanmu?', + options: [ + 'Tidak Membantu', + 'Kurang Membantu', + 'Cukup Membantu', + 'Membantu', + 'Sangat Membantu', + ], + }, + { + question: 'Apakah kamu akan merekomendasikan platform ini ke rekanmu?', + options: ['Ya', 'Tidak', 'Mungkin'], + }, +]; + +export const FeedbackModal: FC = ({ + open, + sessionId, + mentorName, + onClose, + onSuccess, +}): ReactElement => { + const [step, setStep] = useState<'rating' | 'detail'>('rating'); + const [rating, setRating] = useState(0); + const [hoverRating, setHoverRating] = useState(0); + const [helpfulness, setHelpfulness] = useState(''); + const [recommend, setRecommend] = useState(''); + const [liked, setLiked] = useState(''); + const [improve, setImprove] = useState(''); + const [testimonial, setTestimonial] = useState(''); + + const mutation = usePostSessionFeedback(sessionId); + + useEffect(() => { + if (open) { + setStep('rating'); + setRating(0); + setHelpfulness(''); + setRecommend(''); + setLiked(''); + setImprove(''); + setTestimonial(''); + } + }, [open]); + + const handleSubmit = async () => { + const parts: string[] = []; + if (liked.trim()) parts.push(`Suka: ${liked.trim()}`); + if (improve.trim()) parts.push(`Tingkatkan: ${improve.trim()}`); + if (testimonial.trim()) parts.push(`Testimoni: ${testimonial.trim()}`); + if (helpfulness) parts.push(`Kebermanfaatan: ${helpfulness}`); + if (recommend) parts.push(`Rekomendasi: ${recommend}`); + const feedbackText = parts.join('. ') || 'Tidak ada komentar tambahan.'; + + try { + await mutation.mutateAsync({ rating, feedback: feedbackText }); + toast.success('Feedback berhasil dikirim ✅ Terima kasih atas waktumu!'); + onSuccess(); + onClose(); + } catch { + toast.error('Gagal mengirim feedback. Coba lagi ya, Senpai!'); + } + }; + + const canNext = + rating > 0 && helpfulness !== '' && recommend !== ''; + const canSubmit = + canNext || liked.trim() !== '' || improve.trim() !== '' || testimonial.trim() !== ''; + + return ( + +
+
+

+ Feedback Mentor +

+ + {step === 'rating' ? '1 dari 2' : '2 dari 2'} + +
+

+ Sesi dengan {mentorName ?? 'mentormu'} +

+ + +
+ +