Next.js Full-Stack School Management App Full Tutorial | Role Based School Dashboard Project
null

Click
Use
to move to a smaller summary and to move to a larger one
Overview of Fullstack School Management Application with Next.js
- The application has different user roles: admin, teacher, student, and parent.
- Each user role has a specific dashboard with different functionalities and limitations.
- The application fetches data from a database to populate the dashboards.
- The admin dashboard includes features like changing the date, viewing scheduled events, and managing announcements.
- The menu provides access to different list pages for teachers, students, and parents, with pagination and search functionality implemented.
- The application uses React Hook Form for input validation in form components.
- Teachers have a dashboard showing their lessons and restricted access to certain features.
- Students have a dashboard displaying their class schedule and limited access to data.
- Parents can view their children's schedules, exam results, and events.
- The application utilizes Prisma ORM and can work with different databases.
- Deployment is done using Hostinger, which offers VPS hosting and easy setup with powerful servers.
- The application's backend is built in Docker, allowing for easy deployment of the app and database server.
Main Structure of the Application and Database Schema Design.
- The application consists of three main elements: app router, components, and server actions.
- The app folder contains the designed pages, while the components folder contains the form components.
- Data is fetched from the database using the pages and forms.
- The database is used for data fetching, mutation, and connection.
- Prisma ORM is used for all database operations, with the preferred database being Postgres.
- The database schema is designed using an AI tool, with various entities such as admin, teachers, subjects, lessons, classes, students, parents, grades, exams, assignments, results, and attendance.
- Teachers can have multiple subjects, lessons, and classes.
- Each class has students and a supervisor (teacher).
- Students have parents, grades, exam/assignment results, and attendance records.
- Multiple students can belong to a grade and a class.
- Lessons have subjects, teachers, exams, and assignments.
- Exams and assignments have results, and students have attendance records for each lesson.
Overview of Application Structure and Prisma Installation
- The application structure includes classes, supervisors (teachers), students, parents, attendance, exams, assignments, and result tables.
- The relationships include students having parents, and each student belonging to a specific class and attending different lessons.
- The attendance status of each student for each lesson is tracked as absent or present.
- Exams and assignments are created for different lessons, and a result table includes the exam or assignment ID, user ID, and score.
- Prisma is installed and used to create and connect to the database.
- Tables are created using the Prisma schema with fields such as ID, username, name, surname, email, address, image, and sex.
Creating relationships in user model
- Define the gender field as a string with options male or female.
- Create the created_at field as a datetime with the default value set to the current date.
- Create a relationship with the parent model, where each student has a parent and a parent can have multiple students.
- Define the parent_id field as a string with a reference to the ID field in the parent model.
- Create a relationship with the teacher model, where each subject can have multiple teachers.
- Define the teacher_id field as an integer with a reference to the ID field in the teacher model.
- Create a relationship with the subject model, where each lesson belongs to a subject.
- Define the subject_id field as an integer with a reference to the ID field in the subject model.
- Create a relationship with the class model, where each lesson belongs to a class.
- Define the class_id field as an integer with a reference to the ID field in the class model.
- Create a relationship with the teacher model, where each lesson has a teacher.
- Define the teacher_id field as an integer with a reference to the ID field in the teacher model.
Designing a User Management System
- The system includes classes for teachers and students.
- Each student belongs to a specific class, identified by a class ID.
- The system tracks student information in a student list table.
- Grades are assigned to students, with grade levels ranging from 1 to 6.
- Exams and assignments are tracked, with each having an ID and title.
- Exams have start and end times, while assignments have start and due dates.
- Lessons are associated with exams and assignments through a lesson ID field.
- The system records the scores for each exam and assignment.
- Attendance is tracked for lessons, with a status of "present" or "absent".
- The system maintains relations between students, lessons, exams, and assignments.
- Announcements are made, with titles and descriptions.
- Events have starting and ending dates, and can be general or specific to a class.
Setting up and using a custom database with Docker and Prisma.
- Removing unnecessary fields and adding unique email and phone fields for teachers and parent grade level for students.
- The "result" field can belong to an exam or assignment events and announcements.
- Saving changes to the database using Docker.
- Using the Postgres image in Docker to create a database container.
- Setting up variables for the database user, password, and name.
- Running the container and obtaining the connection string.
- Using Prisma to save changes to the database.
- Viewing the generated tables and relationships in Prisma Studio.
- Fetching data using Prisma.
- Using a seed file to populate the tables.
Setting up Prisma and creating initial data
- Prisma client is required to perform CRUD operations in the application.
- Use "Prisma DB seat" command to manually run the seed file.
- Update package.json with required dependencies.
- Initialize Prisma client using "const Prisma = new PrismaClient()" and export it.
- In development mode, create only one instance of Prisma client to prevent multiple clients.
- Use "MPX Prisma DB seat" to seed initial data in the database.
- Make sure to check schema for any required fields.
- Reset the database if needed using "MPX Prisma migrate reset" command.
- Use Prisma Studio to check if the data has been successfully seeded.
- Fetch data using Prisma client and learn how to reset the database if needed.
Modifying Teacher Model and Fetching Data
- Modifying the teacher model to include fields like username, image, subjects, and classes.
- Adding the necessary code to fetch data from the teacher table using Prisma.
- Including the related tables like subjects and classes in the fetched data.
- Displaying the names of subjects and classes in the table by mapping through them and using the subject name and class name fields.
Pagination and Fetching Data
- We can use the pagination component to display a limited number of items on each page.
- The current page number can be stored in the URL to easily track and update the page.
- The page number can be obtained from the URL using the next CHS library.
- We can fetch different sets of items by using the skip method and multiplying the page number by the desired number of items per page.
- The page number can be transformed into an integer if necessary.
Creating Pagination Component and Updating Page Number
- Created a new file for settings and exported a constant named "itemPerPage" with a value of 10.
- Imported the "itemPerPage" constant in another file and updated the value to 5.
- Used the "Prisma" library to fetch the total number of teachers in the database.
- Implemented a Prisma transaction method to fetch both the data and the count in a single function.
- Passed the count and the current page number to the pagination component.
- Defined the types for the page and count props in the pagination component.
- Calculated the total page number using the count and the "itemPerPage" value.
- Created buttons for each page number using the array function "Array.from" and mapped over it.
- Added a condition to highlight the active page.
- Implemented a click event to change the page number.
- Used the "useRouter" hook from the navigation package to handle routing.
- Created a function to handle the page change and pass the new page number to the URL params.
Updating URL parameters based on user actions and implementing disable attribute
- Using existing params and new URL search params to fetch and return all existing params in the URL.
- Changing the page number in the URL while keeping other items unchanged.
- Converting the page number to a string to use it in the URL string.
- Pushing the new params to the URL while keeping the existing ones.
- Implementing disable attribute for previous and next buttons based on certain conditions.
- Checking if there are previous items per page to enable or disable the previous button.
- Checking if there are next items per page to enable or disable the next button.
- Disabling the next button if the number of existing items plus the number of items per page is not smaller than the total count.
- Fixing a typo in the search query for the student page.
- Opening the teachers page with only the teachers belonging to the selected student.
Creating URL and Role Conditions for Query Params
- By passing the class ID of a student, the lessons for that class can be found.
- Clicking on a button updates the query params to open the list page for teachers of that class.
- The class ID is used in a where condition to find specific teachers.
- The lessons of the selected teacher and the classes of those lessons are found.
- The class ID in the lessons should match the query param class ID.
- Different queries can be used to filter the results based on different fields.
- Query params need to be protected and have rules based on different roles (admin, teacher, student).
- A search component updates the URL with a search query and searches for different fields based on the page.
- URL conditions and role conditions need to be implemented to handle the query params properly.
Writing Where Conditions and Protecting Query Params with Prisma
- Writing where conditions in Prisma allows for easier and error-free filtering of data.
- By using Prisma, any mistakes in the where condition will be caught and result in an error.
- Prisma also provides a list of available options for the query, making it easier to write conditions.
- The where condition can be used to filter data based on specific fields, such as class ID.
- Using the where condition helps protect private data, as query parameters can be filtered before reaching the database.
- The same approach can be used in the search component, where the search params can be updated based on user input.
- The search params can be used to search for specific fields, such as teacher name, by using the contains method and setting it as case-insensitive.
Updating Page Queries for Prisma Student and Parent List
- Updating the page query to search for students based on student name.
- Modifying the teacher page to open the students list and pass the teacher ID as a parameter.
- Fetching all students of a teacher by using the teacher ID from the class and lessons.
- Importing Prisma library and patching all the students in the student table.
- Adding the user class to the student table.
- Importing item per page and student.
- Adding page number and count number as parameters for the page query.
- Using student table type and adding the user class to the page query.
- Changing the column names in the row to match the correct values.
- Handling the case where there is no image by using a default avatar.
- Changing the form model to handle numbers as strings for users and integers for others.
- Implementing the teacher link to pass the teacher ID to the single teacher page.
- Adding the ability to search for parents based on parent name.
- Importing Prisma and using the parent table to search for parents based on input.
Retrieving Data for Students, Subjects, Classes, and Lessons
- Create an array of student data to store multiple students.
- Use the map function to return the names of the students and separate them using join.
- Import Prisma to handle database operations.
- Implement pagination using the "page" and "count" parameters.
- Search for student names in the database.
- Retrieve data for subjects and teachers related to those subjects.
- Include teachers in the subjects table.
- Implement pagination for subjects.
- Search for subject names in the database.
- Retrieve classes and the supervisor (teacher) associated with each class.
- Include teachers and the teacher name in the classes table.
- Implement pagination for classes.
- Search for class names in the database.
- Retrieve lessons for a specific teacher.
- Pass the teacher ID to retrieve the lessons associated with that teacher.
- Implement pagination for lessons.
- Search for lesson names in the database.
Creating Function for Fetching Lessons and Exams
- Creating a common function for fetching lessons and exams may make the code more complicated and harder to understand.
- Different rules and requirements necessitate separate functions for fetching lessons and exams.
- To fetch lessons, we need to import the lesson table and include the subject, class, and teacher tables.
- Instead of fetching unnecessary data, we can use the select function to specify the fields we need (e.g., teacher name, class name, subject name).
- Clicking on a link will fetch the lessons belonging to a specific teacher.
- For the student link, we can fetch lessons belonging to a specific class by passing the class ID.
- The search input can be used to search for lessons based on subject name and teacher name.
- When working with the exam table, we only need to fetch the lesson table, and then include the subject, class, and teacher tables within it.
Adding functionality for selecting name, class, and teacher and displaying them in different pages
- Implement select name functionality for true selection.
- Add fields for name and surname in the teacher section.
- Include class in the teacher section.
- Import necessary modules and modify the exam type list.
- Include lesson and subject class within the exam type list.
- Access name, class name, teacher name, and surname within the lesson section.
- Transform the date into day, month, and year format using time format.
- Import Prisma and modify the exam query with input parameters.
- Check for subject name in the lesson section.
- Include teacher exams and student exams by passing class ID and teacher ID.
- Add the teacher ID and class ID parameters in the query for lesson not class ID.
- Copy and paste the code for exams, assignments, and results in different pages.
- Modify the code for assignments by replacing start date with due date.
- Include the same parameters for assignment type, subject type, class, and teacher.
Fetching Data for Exam or Assignment Results
- Fetching the student's name and surname.
- Fetching the exam or assignment details, including the lesson, teacher, and class.
- Selecting only the necessary fields for the teacher's name and surname.
- Handling both exam and assignment data separately.
- Returning the assessment type (exam or assignment), ID, title, student name and surname, teacher name and surname, class name, and start time or start date.
Implementing Data Fetching for Events and Announcements
- Create query options for exam and student data.
- Set the query to check the title of the exam and student name, using case-insensitive mode.
- Only retrieve a single item for the student page.
- Use the student ID from the result data.
- Implement event and announcement data fetching.
- Fetch event data using the event title and class table.
- Use the class name and start time for displaying event details.
- Format the start and end times to display only the hour.
- Implement announcement data fetching.
- Fetch announcement data using the announcement title.
- Display the announcement date and class name.
- Ensure that only admins can update or delete announcements.
- Restrict students and teachers to only see their own exams and announcements.
Authentication and User Roles in a School Management Application
- Students, teachers, and parents cannot create accounts; only the admin can create and delete users.
- The login process is used for users to access the system.
- User roles need to be determined after the login process to protect routes.
- Next.js middleware will be used to intercept page requests and check authentication and user roles.
- Clerk is used for authentication, providing an easy implementation in 5 minutes.
- Clerk takes care of sessions, tokens, cookies, security, and social logins.
- Environment variables need to be set for the application, including the Clerk API keys.
- Middleware needs to be created to handle authentication and user role checks.
- Different rules can be added for different user roles.
- The application needs to be wrapped with the ClerkProvider to access user data in all pages and components.
Creating a Login Page with Custom Signin Component Using Clark Elements
- We can import the necessary components from Clark Next.js to create our login page.
- For testing purposes, we can use the pre-existing users in the dashboard.
- We can create our signin page and use the homepage as the signin path in our application.
- We can create a custom signin component using Clark Elements for a more personalized design.
- We can use the root and step components to create a simple signin flow with username and password fields.
- The signin action component can be used for the login button, and clor Global error can display any errors.
- We need to make sure that our component is a client component and center everything on the login page.
- We can customize the style of our signin component by adding specific styles.
Creating a Login Page with Styling
- Set a white background with padding and a rounded MD shape.
- Center all elements vertically using Flexbox with a column layout and a gap between each item of 2.
- Add a title (H1 tag) with the name of the application.
- Create an H2 tag with the message "Sign in to your account".
- Display any errors in the "Clark Global error" component.
- Create a "Clark.field" component for the username input field, including a label and an input with type "text" and the required attribute.
- Display any errors related to the username in the "Clark.field.error" component.
- Create a similar field for the password input field, with a label and an input with type "password".
- Add a "Sign in" button with an action to submit the form.
- Hide the login page if the user is already authenticated.
- Add a "User button" component to display user information and a logout option.
User Roles, User Information, and Route Protection in Clark
- In the Pro version of Clark, organizations can be used to assign custom roles. In the free version, custom roles can be assigned using user metadata.
- The server component offers the "off" and "current user" methods to retrieve user information, while the client component provides the "useAuth" and "useUser" hooks for the same purpose.
- User information includes the user ID, session ID, and token, along with any custom metadata, such as the role.
- The role can be used to redirect users to specific pages based on their role.
- The "useEffect" hook can be used to check the user's role and redirect them accordingly.
- The "useRouter" hook from the "next/router" package can be used for redirection.
- Middleware can be used to protect routes. The "CreateRouteMatcher" method allows for defining protected routes.
- By using the "protect" method in the authentication middleware, users can be redirected to the sign-in page if they try to access protected routes.
Defining different access rules for each page based on user roles
- Access rules are defined in the settings file, which includes a list of pages and the user roles allowed to view them.
- Each page has different access rules based on the user roles.
- Access rules are stored as an object using object keys, with routes as the keys and the allowed roles as the values.
- The user's role is obtained from the session claims, specifically from the public metadata.
- If the user's role is not included in the allowed roles for a page, they are redirected to a different page.
- By using this access map, the application can determine which pages can be viewed by different user roles.
Modifying Permissions for Different User Roles
- Changing the term "user" to "current user"
- Creating a constant for the user's role: user.publicMetadata.role
- Allowing only admins to update or delete announcements
- Fetching the user's role from authentication instead of temporary data
- Hiding the actions column if the user is not an admin
- Creating a separate file for role-related functions
- Allowing admins and teachers to create assignments
- Filtering the assignments to show only those belonging to the current user
Role-based Access Control in School Management Application
- Different user roles exist in the application.
- Users need to be logged in and have the appropriate role to access certain pages.
- User IDs are used to determine the user's role.
- The application supports roles for teachers, students, and parents.
- Teachers can view and manage assignments, classes, and events.
- Students can view their own assignments and events related to their classes.
- Parents can view assignments and events related to their children's classes.
- Administrators have full access and can create, update, and delete assignments, classes, and events.
- Access to actions and menu options is restricted based on the user's role.
Access control conditions for different user roles.
- If the class ID is null, patch it.
- Use the current user ID as the teacher ID in the query.
- Use the current user ID as the student ID in the query.
- Use the current user ID as the parent ID in the query.
- Check for the conditions for each role (admin, teacher, student, parent) in the query.
- Show only the events, announcements, and exams that belong to the user's class or are relevant to their role.
- Allow admins and teachers to update or delete exams, and allow them to create new exams.
- Show only the exams that belong to the user's class or are relevant to their role.
- Only allow admins to add new lessons.
- Show all lessons to admins and teachers, but only allow admins to add new ones.
- Show only the lessons that belong to the user's class or are relevant to their role.
Creating Base Route Protection and Data Patching
- Only the admin can create, delete, or update parents.
- The table name for parents is correct.
- Admin or teacher can update or delete results.
- Only admin or teacher can update or delete results.
- Admin or teacher can view the exam and assignment tables.
- Students can view the assignment table.
- Parents can view the student table.
- Only admin can delete or update students.
- Teachers can view all the students.
- Only admin can view the subjects table.
- Admin data can be fetched.
- User counts are patched dynamically using the model map.
- The count chart component is a client component that fetches data.
Creating a Component for Fetching and Passing Data
- The user is creating a component to fetch data and pass it to another component.
- They are using an async function to fetch the data.
- They are using Prisma and the Group By function to retrieve the number of boys and girls.
- They are logging the fetched data to the console.
- They are filtering the data to separate boys and girls.
- They are using the Math library to calculate the percentage of boys and girls.
- They are creating a container component for the attendance chart.
- They are passing the fetched data as props to the attendance chart component.
Fetching Data for Attendance by Week
- Use Prisma to fetch attendance data for the current week.
- Determine the latest Monday based on the current day of the week.
- Create an object to store attendance data for each weekday.
- Update the attendance map with data from the fetched items.
Updating items based on the day of the week and displaying events in a calendar.
- Creating a map to track attendance with present and absent numbers for each day of the week.
- Using the day of the week to update the map when an item is present or absent.
- Transforming the map data to fit the required format (day name, present, absent).
- Fetching data for the event list component based on the selected date in the calendar.
- Implementing a container component to handle the state and logic for changing the date.
- Updating the URL when the date changes using the router.
- Displaying the event list component when the date changes and fetching the relevant data.
- Updating the calendar component with the selected date and passing the fetched data to the event list component.
- Creating a user-friendly UI for the calendar component.
Fetching and Filtering Data in Component
- Use date parameter from search params to fetch events.
- Transform date parameter into a date if it exists, otherwise use today's date.
- Fetch data from Prisma R table based on start time condition using the date.
- Map through the fetched data and display event details.
- Fetch announcements based on user role and user ID.
- If user role is admin, display all announcements.
- If user role is teacher, display announcements without a class ID.
- Display announcements specific to user's class ID for other user roles.
Steps to Create a Conditional User Interface
- Define roll conditions based on user roles (teacher, student, parent).
- Set conditions to check the class and lessons based on the user's role.
- Implement logic to display specific data based on the user's role (e.g., announcements, schedule).
- Format dates and display relevant information in the user interface.
- Include conditional rendering to handle cases when there is no data or when the user is an admin.
- Design and create appropriate components for each user type (e.g., admin page, teacher page, student page).
- Fetch and retrieve necessary data using Prisma or relevant database queries.
- Implement conditional rendering based on the user type to display the correct data in the UI (e.g., teacher's calendar or student's calendar).
- Pass data as props to relevant components for rendering.
- Test and verify the functionality of the conditional user interface.
Updating the format and date calculation for temporary data.
- Format the data for title, start, and end dates before sending it.
- Create a user ID for teacher, student, and parent.
- Update the date for lessons to prevent them from disappearing in the future.
- Calculate the current work week from Monday to Friday.
- Set the start and end dates of the week based on the current day of the week.
- Ensure that the date calculation considers weekends and adjusts accordingly.
Adjusting Schedule to Current Week
- The function "adjustScheduleToCurrentWeek" is created to modify the start and end dates of lessons based on the current week.
- The function takes an array of lessons as input, which includes the lesson title, start date, and end date.
- The start and end dates of each lesson are adjusted based on the day of the week they fall on.
- The function calculates the difference in days between the lesson day of the week and Monday.
- The start date is adjusted by adding the number of days from Monday to the start of the week.
- The end date is adjusted by changing the hours, minutes, and seconds to match the original end time.
- The adjusted lesson data, including the new start and end dates, is returned.
- The adjusted schedule is used in the component by calling the "adjustScheduleToCurrentWeek" function and passing the lesson data as an argument.
Creating Subject Form and Updating List Pages
- Created a new form component called "SubjectForm" to handle subject creation and update.
- Imported the necessary dependencies and set up the form validation schema.
- Added the "SubjectForm" component to the list of forms used in the menu.
- Updated the list pages to show a loading indicator while data is being fetched.
- Created a new component called "Loading" to display a loading spinner or skeleton screen.
- Imported and used the "Loading" component in the list pages.
- The subject form is similar to the teacher form but with different fields and data handling.
Creating a form and using react hook form with validation and server actions.
- Create a form using react hook form.
- Use react hook form to validate input data on submit.
- Use react hook form to send the validated data to the server.
- Create a file for form validations.
- Define a schema for the form input.
- Add input fields to the form using the schema.
- Display appropriate messages for validation errors.
- Create server actions file for data mutations.
- Define a server action to create a subject.
- Extract the validated data from the form and pass it to the server action.
- Display the data in the server terminal to verify it.
- Use the data to update the database using Prisma.
Creating a Subject Table and Form Validation in Next.js
- Use the Prisma subject table and create method to add new data.
- Implement form validation to ensure the data is valid before adding it to the table.
- Revalidate the path to return the fresh data after adding a new item.
- Keep track of the form state using the useFormState hook.
- Call the form action instead of directly calling the action to handle the form submission.
- Define the form state to store the success and error states.
- Show an error message if there is an error in the form submission.
- Use a library called react-toastify to show notifications for successful form submissions.
Summary of Code Explanation
- The code is implementing a form for creating and updating subjects.
- The form includes a toast notification component for displaying success or error messages.
- The position and theme of the toast component can be customized.
- The code uses the useState and useEffect hooks from React for managing state and side effects.
- The code also uses the useRouter hook from Next.js for client-side navigation.
- The form has separate actions for creating, updating, and deleting subjects.
- The form includes validation for the ID field in the update action.
- The toast component is closed after a successful action.
- The form includes a button to open and close the form, and the open state is managed using useState and set state actions.
Updating the Delete Subject Form to Include Related Data
- Created a delete action map to handle different delete actions based on the table name.
- Added an input field for the ID of the subject to be deleted.
- Converted the ID value to a string or number depending on the table type.
- Implemented fetching and displaying of related data for the subject form, specifically teachers.
- Updated the form container to include related data fetching and passing it to the form model.
Updating the Subject Form and Adding Select Input for Teachers
- Add an array field for teachers in the form validation schema.
- Add a select input for teachers in the form.
- Update the action to include the teacher ID when updating a subject.
- Update the action to handle both create and update modes.
- Add the teacher options dynamically from the related data.
- Pass the teacher IDs when creating a new subject.
- Add the selected teachers' IDs when updating a subject.
- Update the subject schema to include the teacher IDs.
- Update the subject schema to use the set method when updating the teachers array.
- Test the form to confirm that it can update and delete teachers successfully.
Actions for Creating and Deleting Classes
- Create a new class
- Get the class schema
- Remove a class
- Get form data for creating a class
- Delete a class
- Get form data for updating a class
- Change form models to use form container
- Add a case for class in form container
- Pass class grades and teachers data to form container
- Update model to include class form
- Import class form
- Add delete action for deleting a class
- Update create and update actions to collect all required data for creating and updating a class
- Pass grade and teacher data to class form
- Open class list and create a new class
- Choose a grade and teacher for the class
- Delete a class using the delete action
Updating and Perfecting the Teacher Form and Related Data
- Updating the teacher form to include the necessary fields and validation.
- Making the email field optional but adding validation for correct email format.
- Modifying the schema to reflect the changes in the form.
- Adding a subjects field in the schema as an optional array of subject IDs.
- Implementing actions for creating, updating, and deleting a teacher.
- Fetching and displaying the subjects related to a teacher in the teachers list.
- Implementing related data feature in the model and setting up the form and state accordingly.
- Making use of the use form state hook to handle form submission and refreshing the page upon success.
- Importing necessary hooks and libraries, and ensuring the correct order of code execution.
Creating and Updating Teachers in the User Interface
- If type is "create", a new teacher is created. Otherwise, the existing teacher is updated.
- The user interface includes fields such as username, email, password, name, surname, phone, address, blood type, and birthday.
- The user can select multiple subjects for the teacher.
- The user interface uses a Cloudinary widget to upload an image.
- The Cloudinary widget requires the cloud name and API key to function properly.
- The user can click on the widget to open it and choose an image.
- After successful uploading, the image URL is returned and stored in a state variable called "image".
- The widget can be closed after the successful upload.
Uploading and Creating User with Image in Database
- Click "Upload this image" to upload an image.
- Open the actions and create a user on the Clark server.
- Get the user ID and send it to the database.
- Use the "create user" function to create a user with the provided username, password, first name, last name, email, phone, address, image, blood type, sex, birthday, and subjects.
- Transform the subject IDs from an array of strings to integers.
- Update the schema to include the fields "birthday" for both teachers and students.
- Apply the schema changes using "MPX Prisma migrate Dev".
- Create a user with the provided information, including the uploaded image.
- Show any errors that occur during the creation process.
- Use the secure URL of the uploaded image, if available.
- Update the user's information, including the image, if necessary.
Updating Teacher Information
- Using the "params" function to retrieve the teacher ID.
- Fetching the single teacher using the Prisma "findUnique" method.
- Checking if the teacher exists and displaying the appropriate message if not.
- Displaying the teacher's image, name, surname, birthday, email, and phone number.
- Patching the subject, lesson, and class counts for the teacher.
- Transforming the teacher's birthday to display only the month, day, and year.
- Making the teacher ID hidden for the update mode.
Updating User Data for Teachers and Students
- Update user data for teachers and students.
- Use the CL client users and update user functions.
- Pass the user ID to specify which user to update.
- Add a condition to return an error if no user ID is provided.
- Use teacher update function and pass the condition (data.ID).
- Allow the password to be optional by checking if data.password is not empty.
- Set new subjects instead of connecting them to avoid duplicate branches.
- Add the option to delete a teacher.
- Implement the same process for students.
- Fetch data for a single student using the params patch.
- Include the class and license information.
- Add error handling if no student is found.
- Fetch student details such as name, blood type, birthday, email, and class.
- Display loading indicator while fetching student information.
- Include the count of lessons in the class.
- Create a component for student attendance and fetch the attendance data separately.
Updating Component to Include User Data
- Using suspense block to handle component loading.
- Displaying different text when the component is loading.
- Receiving the user's student ID as a prop.
- Fetching attendance data using Prisma's `do attendance find` method.
- Filtering the attendance data based on the student ID and date condition.
- Calculating the total days and present days using the attendance data.
- Calculating the attendance percentage by dividing present days by total days and multiplying by 100.
- Updating the schedule component to accept either the teacher ID or class ID.
- Passing the student's class ID to the schedule component on the student page.
- Updating the form model on the students page.
- Adding actions for deleting, updating, and creating students.
- Creating the student schema with ID, username, password, name, surname, grade ID, class ID, and parent ID.
- Implementing input validation for grade ID and parent ID.
- Fetching the class data to check if there's space for a new student.
Managing student capacity in a class
- Include the number of students in the class to calculate available space.
- Return an error if the class is at full capacity.
- Add new students to the class.
- Update student information.
- Delete students from the class and the server.
- Display the grades and classes for a student.
- Show the number of empty spaces in the class.
Adding Upload Widget and Modifying the Form for Exams
- The user plans to add an upload widget to the application.
- The user wants to make some changes to the layout of the application to improve the appearance.
- A new field called "parent ID" needs to be created for the form.
- The user is able to select classes and their capacities.
- The user wants to fetch all the parents, but it is not the ideal solution.
- The user is able to create, update, and delete classes.
- The attendance card is opened to check the attendance.
- The user wants to add a button to the teacher page and copy it to the student page.
- The username and other details can be updated by the user.
- The user is able to delete a user and it is successfully deleted.
- The user suggests not repeating the same steps for other forms.
- As a teacher, the user wants to add exams, assignments, and results.
- The user wants to set a condition where only the teacher's lesson IDs can be added for exams.
Updating and Deleting Exams with Form Validation and User Roles
- Exam form can be used for creating and updating exams.
- Form validation is used to ensure required fields are filled in.
- The form includes fields for exam title, start time, end time, and lesson ID.
- The lesson ID is selected from a list of lessons.
- The user role is checked to determine if the exam belongs to the user.
- Only exams belonging to the user can be deleted.
- Only lessons belonging to the user can be selected for creating a new exam.
- A Prisma query is used to check if the lesson belongs to the user before creating a new exam.
- The title, start time, end time, and lesson ID are used to create or update the exam.
- The form allows selecting any date and hour for the exam.
- The lessons are not displayed because the user ID is missing from the schema.
- The user ID is added to the schema to display the lessons.
- The updated form is tested with a new exam and existing exam.
Deploying the Application with Docker
- Move the role and user ID declarations inside the server component to avoid errors.
- Ensure the list components and form container are placed inside their respective containers.
- Add the router and type dependencies to the forms.
- Fetch the data in the parent page to display different big calendar components for each child.
- Create a Docker configuration file (dockerfile) for running the database server and deploying the Next.js application.
- Define the services in the docker-compose file, including the database (Postgres) and the Next.js application.
- Set the environment variables for the database in the docker-compose file.
- Specify the container names and port numbers.
- Add volumes if necessary.
- Copy and paste the necessary code from the GitHub repository.
Setting up and running a Next.js application with PostgreSQL in Docker container.
- Create a Docker container for the Next.js application.
- Set the container name and port numbers.
- Pass environment variables, including the database URL.
- Use the appropriate version of Node.js (e.g., Node.js 18) in the Dockerfile.
- Install dependencies using the package.json file and build the application.
- Run MPX Prisma generate to deploy the Prisma schema.
- Add the project to the GitHub repository.
- Add SSH key to the hosting panel for connecting to the VPS.
- Clone the project on the VPS.
- Create and add environment variables file (e.g., .env) with necessary variables.
- Run the Docker containers using the command "docker-compose up --build".
- Access the application using the specified port number.
- Verify functionality by logging in, adding, updating, and deleting data.
Creating a User Profile Form with Various Fields
- The user profile form includes fields for name, surname, address, blood type, and date.
- The form allows users to select their preferred subject.
- The user can create and submit the profile form successfully.
Application Features and Database Structure
- The application has different user roles: admin, teacher, student, and parent.
- Each user role has a specific dashboard with different functionalities and limitations.
- The admin dashboard includes features like changing the date, viewing scheduled events, and managing announcements.
- The application fetches data from a database to populate the dashboards.
- The menu provides access to different list pages for teachers, students, and parents, with pagination and search functionality.
- Input validation in form components is implemented using React Hook Form.
- Teachers have a dashboard showing their lessons and restricted access to certain features.
- Students have a dashboard displaying their class schedule and limited access to data.
- Parents can view their children's schedules, exam results, and events.
- The application utilizes Prisma ORM and can work with different databases.
- Deployment is done using Hostinger, offering VPS hosting and easy setup with powerful servers.
- The application's backend is built in Docker, allowing for easy deployment of the app and database server.
- The application consists of three main elements: app router, components, and server actions.
- The database schema is designed using an AI tool, with entities such as admin, teachers, subjects, lessons, classes, students, parents, grades, exams, assignments, results, and attendance.
- Relationships include students having parents, each student belonging to a specific class, and teachers having multiple subjects, lessons, and classes.
- Exams and assignments are created for different lessons, and a result table includes the exam or assignment ID, user ID, and score.
Updating Database Fields, Seeding Data, and Implementing Pagination and Search
- Removing unnecessary fields and adding unique email and phone fields for teachers and parent grade level for students.
- Saving changes to the database using Docker and the Postgres image.
- Using Prisma to view and modify the generated tables and relationships in Prisma Studio.
- Fetching data from the database using Prisma.
- Using a seed file to populate the tables and manually running it using the "Prisma DB seat" command.
- Initializing and using Prisma client to perform CRUD operations in the application.
- Resetting the database if needed using the "Prisma migrate reset" command.
- Modifying the teacher model to include additional fields like username, image, subjects, and classes.
- Fetching data from the teacher table using Prisma and including related tables like subjects and classes.
- Using pagination to display a limited number of items on each page.
- Storing and updating the current page number in the URL using the "next CHS library".
- Fetching different sets of items by using the skip method and multiplying the page number by the desired number of items per page.
- Implementing a constant for the number of items per page and updating it in a separate file.
- Fetching the total number of teachers in the database using Prisma.
- Implementing pagination components and functionality to navigate between pages.
- Handling routing and updating the page number in the URL using the "useRouter" hook.
- Implementing disable attribute for previous and next buttons based on certain conditions.
- Fixing a typo in the search query for the student page.
- Opening the teachers page with only the teachers belonging to the selected student.
Summary of Code Implementation in Prisma
- Prisma allows for easier and error-free filtering of data using the where condition.
- Mistakes in the where condition are caught and result in an error.
- Prisma provides a list of available options for the query, making it easier to write conditions.
- The where condition can be used to filter data based on specific fields, such as class ID.
- Using the where condition helps protect private data by filtering query parameters before reaching the database.
- The same approach can be used in the search component, where search params can be updated based on user input.
- The search params can be used to search for specific fields, such as teacher name, using the contains method and setting it as case-insensitive.
- Various modifications are made to handle pagination, fetch specific data, and implement different functionality for teachers, students, parents, subjects, classes, lessons, exams, and assignments.
- The code includes importing necessary modules, querying the database, manipulating data, and returning specific fields.
Implementation Details for Exam and Student Data Query, User Roles, and Authentication
- Set query options for exam and student data to check the title of the exam and student name in case-insensitive mode.
- Retrieve only a single item for the student page using the student ID from the result data.
- Implement event data fetching using the event title and class table.
- Display event details using the class name and start time, formatted to display only the hour.
- Implement announcement data fetching using the announcement title.
- Display the announcement date and class name.
- Restrict only admins to update or delete announcements.
- Restrict students and teachers to see only their own exams and announcements.
- Only the admin can create and delete users; students, teachers, and parents cannot create accounts.
- Use the login process for users to access the system.
- Determine user roles after the login process to protect routes.
- Use Next.js middleware to intercept page requests and check authentication and user roles.
- Use Clerk for authentication, providing easy implementation in 5 minutes.
- Clerk takes care of sessions, tokens, cookies, security, and social logins.
- Set environment variables for the application, including the Clerk API keys.
- Create middleware to handle authentication and user role checks.
- Different rules can be added for different user roles.
- Wrap the application with the ClerkProvider to access user data in all pages and components.
- Import necessary components from Clark Next.js to create the login page.
- Use pre-existing users in the dashboard for testing purposes.
- Create a signin page and use the homepage as the signin path in the application.
- Create a custom signin component using Clark Elements for a personalized design.
User Roles and Access Control
- Changing the term "user" to "current user".
- Creating a constant for the user's role: user.publicMetadata.role.
- Allowing only admins to update or delete announcements.
- Fetching the user's role from authentication instead of temporary data.
- Hiding the actions column if the user is not an admin.
- Creating a separate file for role-related functions.
- Allowing admins and teachers to create assignments.
- Filtering the assignments to show only those belonging to the current user.
- Different user roles exist in the application: teachers, students, parents, and administrators.
- Access to certain pages is restricted based on the user's role.
- User IDs are used to determine the user's role.
- Teachers can view and manage assignments, classes, and events.
- Students can view their own assignments and events related to their classes.
- Parents can view assignments and events related to their children's classes.
- Administrators have full access and can create, update, and delete assignments, classes, and events.
- Show only the events, announcements, and exams that belong to the user's class or are relevant to their role.
- Allow admins and teachers to update or delete exams and create new exams.
- Show only the exams that belong to the user's class or are relevant to their role.
- Only allow admins to add new lessons and show all lessons to admins and teachers.
- Show only the lessons that belong to the user's class or are relevant to their role.
- Only the admin can create, delete, or update parents.
- Admin or teacher can update or delete results.
Implementing User Roles and Conditional Rendering in a Web Application
- Define different roll conditions based on user roles such as teacher, student, and parent.
- Set conditions to check the user's class and lessons based on their role.
- Implement logic to display specific data (e.g., announcements, schedule) based on the user's role.
- Format dates and display relevant information in the user interface.
- Use conditional rendering to handle cases when there is no data or when the user is an admin.
- Design and create appropriate components for each user type (e.g., admin page, teacher page, student page).
- Fetch and retrieve necessary data using Prisma or relevant database queries.
- Implement conditional rendering based on the user type to display the correct data in the UI.
- Pass data as props to relevant components for rendering.
- Test and verify the functionality of the conditional user interface.
Updating Teacher Form and Schema
- Add an array field for teachers in the form validation schema.
- Add a select input for teachers in the form.
- Update the action to include the teacher ID when updating a subject.
- Update the action to handle both create and update modes.
- Add the teacher options dynamically from the related data.
- Pass the teacher IDs when creating a new subject.
- Add the selected teachers' IDs when updating a subject.
- Update the subject schema to include the teacher IDs.
- Update the subject schema to use the set method when updating the teachers array.
- Test the form to confirm that it can update and delete teachers successfully.
Summary of User's Requests and Actions
- Implementing suspense block for handling component loading.
- Displaying different text when component is loading.
- Fetching attendance data based on student ID.
- Calculating total days and present days from attendance data.
- Calculating attendance percentage.
- Updating schedule component to accept teacher ID or class ID.
- Passing student's class ID to schedule component on student page.
- Updating form model on student page.
- Adding actions for deleting, updating, and creating students.
- Creating student schema with various fields.
- Implementing input validation for grade ID and parent ID.
- Fetching class data to check available space for new student.
- Adding new students to class.
- Updating student information.
- Deleting students from class and server.
- Displaying grades and classes for a student.
- Adding upload widget to application.
- Making changes to layout of application for improved appearance.
- Creating new field called "parent ID" for form.
- Selecting classes and their capacities.
- Fetching all parents.
- Creating, updating, and deleting classes.
- Checking attendance using attendance card.
- Adding button to teacher page and copying to student page.
- Allowing user to update username and other details.
- Deleting user.
- Not repeating steps for other forms.
- Adding exams, assignments, and results as a teacher.
- Setting condition for lesson IDs for exams.
- Validating exam form.
- Using Prisma query to check lesson ownership.
- Creating or updating exams.
- Displaying lessons with user ID added to schema.
- Organizing components in containers.
- Adding router and type dependencies to forms.
- Fetching data for displaying different calendar components.
- Creating Docker configuration file for running database server and deploying application.