Classlist ve NewClassroom

This commit is contained in:
Sedat ÖZTÜRK 2025-08-27 16:19:08 +03:00
parent 9d88671c3a
commit 7e402d352c
2 changed files with 78 additions and 91 deletions

View file

@ -10,7 +10,7 @@ export interface User {
} }
export interface ClassroomDto { export interface ClassroomDto {
id: string id?: string
name: string name: string
description?: string description?: string
subject?: string subject?: string

View file

@ -27,13 +27,20 @@ const ClassList: React.FC = () => {
const navigate = useNavigate() const navigate = useNavigate()
const { user } = useStoreState((state) => state.auth) const { user } = useStoreState((state) => state.auth)
const newClassEntity = { const newClassEntity: ClassroomDto = {
id: crypto.randomUUID(),
name: '', name: '',
description: '', description: '',
subject: '', subject: '',
teacherId: user.id,
teacherName: user.name,
scheduledStartTime: '', scheduledStartTime: '',
duration: 60, duration: 60,
maxParticipants: 30, maxParticipants: 30,
isActive: false,
isScheduled: true,
participantCount: 0,
canJoin: false,
settings: { settings: {
allowHandRaise: true, allowHandRaise: true,
allowStudentChat: true, allowStudentChat: true,
@ -46,10 +53,7 @@ const ClassList: React.FC = () => {
}, },
} }
const [classList, setClassList] = useState<ClassroomDto[]>([]) const [classList, setClassList] = useState<ClassroomDto[]>([])
const [classroom, setClassroom] = useState<ClassroomDto>(newClassEntity)
const [newClassroom, setNewClassroom] = useState(newClassEntity)
const [editingClass, setEditingClass] = useState<ClassroomDto | null>(null)
const [deletingClass, setDeletingClass] = useState<ClassroomDto | null>(null)
const [showCreateModal, setShowCreateModal] = useState(false) const [showCreateModal, setShowCreateModal] = useState(false)
const [showEditModal, setShowEditModal] = useState(false) const [showEditModal, setShowEditModal] = useState(false)
@ -75,32 +79,16 @@ const ClassList: React.FC = () => {
const handleCreateClass = async (e: React.FormEvent) => { const handleCreateClass = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
const newClass: ClassroomDto = {
...newClassroom,
id: crypto.randomUUID(),
teacherId: user.id,
teacherName: user.name,
isActive: false,
isScheduled: true,
participantCount: 0,
actualStartTime: '',
canJoin: false,
settings: {
...newClassroom.settings,
defaultMicrophoneState: newClassroom.settings.defaultMicrophoneState as 'muted' | 'unmuted',
defaultCameraState: newClassroom.settings.defaultCameraState as 'on' | 'off',
},
}
try { try {
await createClassroom(newClass) await createClassroom(newClassEntity)
getClassroomList() getClassroomList()
setShowCreateModal(false) setShowCreateModal(false)
setNewClassroom(newClassEntity) setClassroom(newClassEntity)
if (newClass.id) { if (classroom.id) {
navigate(ROUTES_ENUM.protected.admin.classroom.classroom.replace(':id', newClass.id)) navigate(ROUTES_ENUM.protected.admin.classroom.classroom.replace(':id', classroom.id))
} }
} catch (error) { } catch (error) {
console.error('Sınıf oluştururken hata oluştu:', error) console.error('Sınıf oluştururken hata oluştu:', error)
@ -109,14 +97,14 @@ const ClassList: React.FC = () => {
const handleEditClass = async (e: React.FormEvent) => { const handleEditClass = async (e: React.FormEvent) => {
e.preventDefault() e.preventDefault()
if (!editingClass) return if (!classroom) return
try { try {
await updateClassroom(editingClass) await updateClassroom(classroom)
getClassroomList() getClassroomList()
setShowEditModal(false) setShowEditModal(false)
setEditingClass(null) setClassroom(newClassEntity)
resetForm() resetForm()
} catch (error) { } catch (error) {
console.error('Sınıf oluştururken hata oluştu:', error) console.error('Sınıf oluştururken hata oluştu:', error)
@ -124,30 +112,30 @@ const ClassList: React.FC = () => {
} }
const openEditModal = (classSession: ClassroomDto) => { const openEditModal = (classSession: ClassroomDto) => {
setEditingClass(classSession) setClassroom(classSession)
setShowEditModal(true) setShowEditModal(true)
} }
const openDeleteModal = (classSession: ClassroomDto) => { const openDeleteModal = (classSession: ClassroomDto) => {
setDeletingClass(classSession) setClassroom(classSession)
setShowDeleteModal(true) setShowDeleteModal(true)
} }
const handleDeleteClass = async () => { const handleDeleteClass = async () => {
if (!deletingClass) return if (!classroom) return
try { try {
await deleteClassroom(deletingClass.id) await deleteClassroom(classroom.id!)
getClassroomList() getClassroomList()
setShowDeleteModal(false) setShowDeleteModal(false)
setDeletingClass(null) setClassroom(newClassEntity)
} catch (error) { } catch (error) {
console.error('Sınıf silinirken hata oluştu:', error) console.error('Sınıf silinirken hata oluştu:', error)
} }
} }
const resetForm = () => { const resetForm = () => {
setNewClassroom(newClassEntity) setClassroom(newClassEntity)
} }
const handleStartClass = (classSession: ClassroomDto) => { const handleStartClass = (classSession: ClassroomDto) => {
@ -422,7 +410,7 @@ const ClassList: React.FC = () => {
</div> </div>
{/* Class Modal (Create/Edit) */} {/* Class Modal (Create/Edit) */}
{(showCreateModal || (showEditModal && editingClass)) && ( {(showCreateModal || (showEditModal && classroom)) && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<motion.div <motion.div
initial={{ opacity: 0, scale: 0.95 }} initial={{ opacity: 0, scale: 0.95 }}
@ -445,8 +433,8 @@ const ClassList: React.FC = () => {
type="text" type="text"
required required
autoFocus={showCreateModal} autoFocus={showCreateModal}
value={newClassroom.name} value={classroom.name}
onChange={(e) => setNewClassroom({ ...newClassroom, name: e.target.value })} onChange={(e) => setClassroom({ ...classroom, name: e.target.value })}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Örn: Matematik 101 - Diferansiyel Denklemler" placeholder="Örn: Matematik 101 - Diferansiyel Denklemler"
/> />
@ -455,10 +443,8 @@ const ClassList: React.FC = () => {
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2">ıklama</label> <label className="block text-sm font-medium text-gray-700 mb-2">ıklama</label>
<textarea <textarea
value={newClassroom.description} value={classroom.description}
onChange={(e) => onChange={(e) => setClassroom({ ...classroom, description: e.target.value })}
setNewClassroom({ ...newClassroom, description: e.target.value })
}
rows={3} rows={3}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Ders hakkında kısa açıklama..." placeholder="Ders hakkında kısa açıklama..."
@ -472,8 +458,8 @@ const ClassList: React.FC = () => {
</label> </label>
<input <input
type="text" type="text"
value={newClassroom.subject} value={classroom.subject}
onChange={(e) => setNewClassroom({ ...newClassroom, subject: e.target.value })} onChange={(e) => setClassroom({ ...classroom, subject: e.target.value })}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Örn: Matematik, Fizik, Kimya" placeholder="Örn: Matematik, Fizik, Kimya"
/> />
@ -486,10 +472,12 @@ const ClassList: React.FC = () => {
<input <input
type="datetime-local" type="datetime-local"
required required
value={newClassroom.scheduledStartTime} value={
classroom.scheduledStartTime ? classroom.scheduledStartTime.slice(0, 16) : ''
}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
scheduledStartTime: e.target.value, scheduledStartTime: e.target.value,
}) })
} }
@ -507,10 +495,10 @@ const ClassList: React.FC = () => {
type="number" type="number"
min="15" min="15"
max="480" max="480"
value={newClassroom.duration} value={classroom.duration}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
duration: parseInt(e.target.value), duration: parseInt(e.target.value),
}) })
} }
@ -526,10 +514,10 @@ const ClassList: React.FC = () => {
type="number" type="number"
min="1" min="1"
max="100" max="100"
value={newClassroom.maxParticipants} value={classroom.maxParticipants}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
maxParticipants: parseInt(e.target.value), maxParticipants: parseInt(e.target.value),
}) })
} }
@ -548,12 +536,12 @@ const ClassList: React.FC = () => {
<label className="flex items-center space-x-3"> <label className="flex items-center space-x-3">
<input <input
type="checkbox" type="checkbox"
checked={newClassroom.settings.allowHandRaise} checked={classroom.settings?.allowHandRaise}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
allowHandRaise: e.target.checked, allowHandRaise: e.target.checked,
}, },
}) })
@ -565,12 +553,12 @@ const ClassList: React.FC = () => {
<label className="flex items-center space-x-3"> <label className="flex items-center space-x-3">
<input <input
type="checkbox" type="checkbox"
checked={newClassroom.settings.allowStudentChat} checked={classroom.settings?.allowStudentChat}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
allowStudentChat: e.target.checked, allowStudentChat: e.target.checked,
}, },
}) })
@ -582,12 +570,12 @@ const ClassList: React.FC = () => {
<label className="flex items-center space-x-3"> <label className="flex items-center space-x-3">
<input <input
type="checkbox" type="checkbox"
checked={newClassroom.settings.allowPrivateMessages} checked={classroom.settings?.allowPrivateMessages}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
allowPrivateMessages: e.target.checked, allowPrivateMessages: e.target.checked,
}, },
}) })
@ -599,12 +587,12 @@ const ClassList: React.FC = () => {
<label className="flex items-center space-x-3"> <label className="flex items-center space-x-3">
<input <input
type="checkbox" type="checkbox"
checked={newClassroom.settings.allowStudentScreenShare} checked={classroom.settings?.allowStudentScreenShare}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
allowStudentScreenShare: e.target.checked, allowStudentScreenShare: e.target.checked,
}, },
}) })
@ -623,12 +611,12 @@ const ClassList: React.FC = () => {
Varsayılan mikrofon durumu Varsayılan mikrofon durumu
</label> </label>
<select <select
value={newClassroom.settings.defaultMicrophoneState} value={classroom.settings?.defaultMicrophoneState}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
defaultMicrophoneState: e.target.value as 'muted' | 'unmuted', defaultMicrophoneState: e.target.value as 'muted' | 'unmuted',
}, },
}) })
@ -645,12 +633,12 @@ const ClassList: React.FC = () => {
Varsayılan kamera durumu Varsayılan kamera durumu
</label> </label>
<select <select
value={newClassroom.settings.defaultCameraState} value={classroom.settings?.defaultCameraState}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
defaultCameraState: e.target.value as 'on' | 'off', defaultCameraState: e.target.value as 'on' | 'off',
}, },
}) })
@ -667,12 +655,12 @@ const ClassList: React.FC = () => {
Varsayılan layout Varsayılan layout
</label> </label>
<select <select
value={newClassroom.settings.defaultLayout} value={classroom.settings?.defaultLayout}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
defaultLayout: e.target.value, defaultLayout: e.target.value,
}, },
}) })
@ -689,12 +677,12 @@ const ClassList: React.FC = () => {
<label className="flex items-center space-x-3"> <label className="flex items-center space-x-3">
<input <input
type="checkbox" type="checkbox"
checked={newClassroom.settings.autoMuteNewParticipants} checked={classroom.settings?.autoMuteNewParticipants}
onChange={(e) => onChange={(e) =>
setNewClassroom({ setClassroom({
...newClassroom, ...classroom,
settings: { settings: {
...newClassroom.settings, ...classroom.settings!,
autoMuteNewParticipants: e.target.checked, autoMuteNewParticipants: e.target.checked,
}, },
}) })
@ -714,7 +702,7 @@ const ClassList: React.FC = () => {
if (showCreateModal) setShowCreateModal(false) if (showCreateModal) setShowCreateModal(false)
if (showEditModal) { if (showEditModal) {
setShowEditModal(false) setShowEditModal(false)
setEditingClass(null) setClassroom(newClassEntity)
resetForm() resetForm()
} }
}} }}
@ -735,7 +723,7 @@ const ClassList: React.FC = () => {
)} )}
{/* Delete Confirmation Modal */} {/* Delete Confirmation Modal */}
{showDeleteModal && deletingClass && ( {showDeleteModal && classroom && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<motion.div <motion.div
initial={{ opacity: 0, scale: 0.95 }} initial={{ opacity: 0, scale: 0.95 }}
@ -754,15 +742,14 @@ const ClassList: React.FC = () => {
</div> </div>
<p className="text-gray-700 mb-6"> <p className="text-gray-700 mb-6">
<strong>"{deletingClass.name}"</strong> adlı sınıfı silmek istediğinizden emin <strong>"{classroom.name}"</strong> adlı sınıfı silmek istediğinizden emin misiniz?
misiniz?
</p> </p>
<div className="flex items-center justify-end space-x-4"> <div className="flex items-center justify-end space-x-4">
<button <button
onClick={() => { onClick={() => {
setShowDeleteModal(false) setShowDeleteModal(false)
setDeletingClass(null) setClassroom(newClassEntity)
}} }}
className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors" className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
> >