Skip to content

Commit

Permalink
(feat): Added hot reloading in our /classes page (#357)
Browse files Browse the repository at this point in the history
* Added functionality for hot reloading in our /classes page

* Added fast refresh for deleting a classroom

* added fast-refresh for editing classes
  • Loading branch information
GuillermoFloresV authored Jul 31, 2023
1 parent 310f75c commit 29457a8
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 32 deletions.
38 changes: 23 additions & 15 deletions components/ClassInviteTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import 'react-toastify/dist/ReactToastify.css';
import { MultiSelect } from 'react-multi-select-component';

export default function ClassInviteTable({
classes,
currentClass,
certificationNames,
userId
userId,
handleDelete,
handleEdit
}) {
const router = useRouter();
const [showOptions, setShowOptions] = useState(false);
const [editOn, setEditOn] = useState(false);
const [formData, setFormData] = useState({});

const getSelectedCerts = () => {
const selectedCerts = classes.selectedCertifications.map(x => x);
const selectedCerts = currentClass.fccCertifications.map(x => x);
return certificationNames.filter(x => selectedCerts.includes(x.value));
};
const [selected, setSelected] = useState(() =>
Expand All @@ -32,7 +34,7 @@ export default function ClassInviteTable({
const copy = async () => {
//Add the full URL to send to student
await navigator.clipboard.writeText(
`${userCurrentDomain}/join/` + classes.classroomId
`${userCurrentDomain}/join/` + currentClass.classroomId
);

toast('Class code successfully copied', {
Expand All @@ -42,7 +44,8 @@ export default function ClassInviteTable({

const deleteClass = async () => {
if (confirm('Do you want to delete this class?') == true) {
const JSONdata = JSON.stringify(classes.classroomId);
const JSONdata = JSON.stringify(currentClass.classroomId);
const classToDelete = currentClass.classroomId;
try {
const res = await fetch(`/api/deleteclass`, {
method: 'DELETE',
Expand All @@ -52,11 +55,10 @@ export default function ClassInviteTable({
body: JSONdata
});
if (res.status === 403) {
router.reload('/classes');
alert('Cannot delete class, not valid user');
} else {
router.reload('/classes');
alert('Successfully Deleted Class');
handleDelete(classToDelete);
alert('Class successfully deleted.');
}
} catch (error) {
alert('Sorry, there was an error on our end. Please try again later.');
Expand All @@ -73,7 +75,7 @@ export default function ClassInviteTable({
return a - b;
});
formData.fccCertifications = fccCertifications;
formData.classroomId = classes.classroomId;
formData.classroomId = currentClass.classroomId;
const JSONdata = JSON.stringify(formData);
try {
const res = await fetch(`/api/editclass`, {
Expand All @@ -87,7 +89,13 @@ export default function ClassInviteTable({
router.reload('/classes');
alert('No changes modified.');
} else {
router.reload('/classes');
const jsonRes = await res.json();
const updatedClassroom = {
classroomName: jsonRes.classroomName,
description: jsonRes.description,
fccCertifications: jsonRes.fccCertifications
};
handleEdit(currentClass.classroomId, updatedClassroom);
alert('Successfully Edited Class');
}
} catch (error) {
Expand Down Expand Up @@ -126,7 +134,7 @@ export default function ClassInviteTable({
>
<div ref={ref} className='group flex items-center'>
<h2 className='text-slate-900 group-hover:text-white text-l font-semibold'>
Classroom: {classes.classroomName}
Classroom: {currentClass.classroomName}
</h2>
{/* <-------Menu Item Selection -----> */}
<div className='wrapper group ml-auto flex items-center'>
Expand Down Expand Up @@ -283,7 +291,7 @@ export default function ClassInviteTable({
id='class-name'
name='classname'
className='appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm'
placeholder={classes.classroomName}
placeholder={currentClass.classroomName}
></input>
</div>
</div>
Expand All @@ -303,7 +311,7 @@ export default function ClassInviteTable({
id='description-text'
name='description'
className='appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm'
placeholder={classes.description}
placeholder={currentClass.description}
></textarea>
</div>
</div>
Expand Down Expand Up @@ -348,10 +356,10 @@ export default function ClassInviteTable({

<div>
<h1 className='text-slate-900 group-hover:text-white text-l'>
{classes.description}
{currentClass.description}
</h1>
</div>
<Link href={`/dashboard/v2/${classes.classroomId}`} passHref>
<Link href={`/dashboard/v2/${currentClass.classroomId}`} passHref>
<button className='border-2 border-fcc-gray-15 bg-fcc-gray-90 text-white font-bold py-2 px-4 rounded'>
View Class
</button>
Expand Down
28 changes: 21 additions & 7 deletions components/modal.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { useState } from 'react';
import { useRouter } from 'next/router';
import { MultiSelect } from 'react-multi-select-component';

export default function Modal({ userId, certificationNames }) {
export default function Modal({
userId,
certificationNames,
setCurrentClassrooms
}) {
const handleCancelClick = () => {
setSelected([]);
setModalOn(false);
Expand All @@ -12,7 +15,6 @@ export default function Modal({ userId, certificationNames }) {
const [selected, setSelected] = useState([]);

const [modalOn, setModalOn] = useState(false);
const router = useRouter();

const clicked = () => {
setModalOn(true);
Expand All @@ -32,9 +34,21 @@ export default function Modal({ userId, certificationNames }) {
},
body: JSON.stringify(formData)
});
router.reload();
alert('Successfully Created Class');
return await response.json();

const jsonRes = await response.json();
let newClassroom = {
classroomName: jsonRes.classroomName,
description: jsonRes.description,
classroomTeacherId: jsonRes.classroomTeacherId,
fccCertifications: jsonRes.fccCertifications,
classroomId: jsonRes.classroomId,
createdAt: jsonRes.createdAt
};
setCurrentClassrooms(currentClassrooms => [
...currentClassrooms,
newClassroom
]);
setSelected([]);
}

return (
Expand Down Expand Up @@ -69,7 +83,7 @@ export default function Modal({ userId, certificationNames }) {
onChange={e =>
setFormData({
...formData,
className: e.target.value,
classroomName: e.target.value,
classroomTeacherId: userId
})
}
Expand Down
7 changes: 3 additions & 4 deletions pages/api/create_class_teacher.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import prisma from '../../prisma/prisma';
import { unstable_getServerSession } from 'next-auth';
import { getServerSession } from 'next-auth';
import { authOptions } from './auth/[...nextauth]';

export default async function handle(req, res) {
//unstable_getServerSession is recommended here: https://next-auth.js.org/configuration/nextjs
const session = await unstable_getServerSession(req, res, authOptions);
const session = await getServerSession(req, res, authOptions);
let user;

if (!req.method == 'POST') {
Expand Down Expand Up @@ -43,12 +43,11 @@ export default async function handle(req, res) {

const createClassInDB = await prisma.classroom.create({
data: {
classroomName: data['className'],
classroomName: data['classroomName'],
description: data['description'],
classroomTeacherId: data['classroomTeacherId'],
fccCertifications: data['fccCertifications']
}
});

return res.json(createClassInDB);
}
4 changes: 2 additions & 2 deletions pages/api/editclass.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default async function handle(req, res) {
return res.status(304).end();
}

await prisma.classroom.update({
const editClassInDB = await prisma.classroom.update({
where: {
classroomId: data.classroomId
},
Expand All @@ -55,5 +55,5 @@ export default async function handle(req, res) {
fccCertifications: data.fccCertifications
}
});
return res.status(200).end();
return res.json(editClassInDB);
}
42 changes: 38 additions & 4 deletions pages/classes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getSession } from 'next-auth/react';
import Modal from '../../components/modal';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useState } from 'react';

export async function getServerSideProps(ctx) {
const userSession = await getSession(ctx);
Expand Down Expand Up @@ -49,7 +50,7 @@ export async function getServerSideProps(ctx) {
classroomId: classroom.classroomId,
description: classroom.description,
createdAt: JSON.stringify(classroom.createdAt),
selectedCertifications: classroom.fccCertifications
fccCertifications: classroom.fccCertifications
})
);

Expand Down Expand Up @@ -77,6 +78,29 @@ export default function Classes({
user,
certificationNames
}) {
let [currentClassrooms, setCurrentClassrooms] = useState(classrooms);
const handleDelete = classToDelete => {
setCurrentClassrooms(currentClassrooms =>
currentClassrooms.filter(
currClass => currClass.classroomId != classToDelete
)
);
};
const handleEdit = (classToEditId, updatedData) => {
const updatedClassrooms = currentClassrooms.map(currClass => {
if (classToEditId == currClass.classroomId) {
return {
...currClass,
classroomName: updatedData.classroomName,
description: updatedData.description,
fccCertifications: updatedData.fccCertifications
};
}
return currClass;
});
setCurrentClassrooms(updatedClassrooms);
};

return (
<>
<ToastContainer
Expand Down Expand Up @@ -108,12 +132,22 @@ export default function Classes({
<h1> Copy invite code by clicking on your preferred class. </h1>
</div>

{<Modal userId={user} certificationNames={certificationNames} />}
{classrooms.map(classroom => (
{
<Modal
userId={user}
certificationNames={certificationNames}
currentClassrooms={currentClassrooms}
setCurrentClassrooms={setCurrentClassrooms}
/>
}
{currentClassrooms.map(classroom => (
<div key={classroom.classroomId}>
<ClassInviteTable
classes={classroom}
currentClass={classroom}
certificationNames={certificationNames}
currentClassrooms={currentClassrooms}
handleDelete={handleDelete}
handleEdit={handleEdit}
userId={user}
></ClassInviteTable>
</div>
Expand Down

0 comments on commit 29457a8

Please sign in to comment.