Admin Panel
The admin panel is a system for managing various aspects of the application, including blog categories, files, orders, roles, stories, users, and more. It is a combination of server-side rendering and dynamic content management to ensure a seamless experience for administrators. The admin panel is protected by authentication and role-based access control, ensuring that only authorized users can access specific sections.
Features
🔐 Role-Based Access Control: Ensures that only authorized users, such as admins, can access specific sections of the admin panel. This is managed through Supabase and Next.js's server-side capabilities.
📝 Dynamic Content Management: Using React for component-based architecture and Supabase for backend data management, provides forms and pages for creating, editing, and viewing different content types such as blog categories, roles, stories, and more.
⚡ Server-Side Rendering: Powered by Next.js's built-in server-side rendering (SSR) features, utilizes server-side rendering to fetch data and render pages dynamically, ensuring that the most up-to-date information is displayed.
🔒 Authentication Protection: Handled through Supabase for authentication and Next.js's middleware for route protection, the admin panel is protected by authentication, ensuring that only logged-in users with the appropriate roles can access it.
🎨 SCSS Styling: The admin panel uses SCSS (Sass) for styling components, providing flexibility and maintainability in the design and appearance of the application.
Screenshots
What's Included
< AdminLayout />
The AdminLayout
component serves as the primary layout for the admin panel, including the sidebar and header for navigation. Component redirects users to the home page if they are not authorized admin users.
AdminLayout
Props
Name | Type | Description |
---|---|---|
children | ReactNode | The main content to be displayed within the layout. |
< Sidebar />
The Sidebar
component displays the navigation links for different sections of the admin panel, such as blog categories, roles, stories, and more.
< Header />
The Header
component displays the admin menu and provides additional context about the current section of the admin panel.
Blog Categories Page
CreateBlogCategoryPage
This page provides a form to create a new blog category. It renders a BlogCategoryForm
wrapped in a Page
component.
EditBlogCategoryPage
This page provides a form to edit an existing blog category. It fetches the blog category data using the getBlogCategory
action and renders the BlogCategoryForm
with the edit
prop.
EditBlogCategoryPage
Props
Name | Type | Description |
---|---|---|
params | object | Contains the id of the blog category to be edited. |
BlogCategoriesPage
This page lists all blog categories and allows administrators to view them. Fetches all blog categories using the getAllBlogCategories
action and renders the BlogCategories
component with the list of categories.
Blog Category Components
< BlogCategories />
Displays a list of blog categories and provides actions for editing and deleting categories.
BlogCategories
Props
Name | Type | Description |
---|---|---|
categories | array | An array of blog category data to be displayed in the table. |
< BlogCategoriesHeader />
Displays the header for the Blog Categories page, including a button to add a new category if there are existing categories.
BlogCategoriesHeader
Props
Name | Type | Description |
---|---|---|
list | boolean | A boolean indicating whether to display the "Add Category" button. |
< BlogCategoryForm />
Handles the creation and editing of blog categories.
BlogCategoryForm
Props
Name | Type | Description |
---|---|---|
edit | boolean | A boolean indicating if the form is in edit mode. |
blogCategory | object | The blog category data being edited (if in edit mode). |
Blog Posts
BlogPostsPage
This page lists all blog posts managed within the system. Fetches all blog posts using the getAllBlogPosts
action and renders the BlogPosts
component with the list of posts.
Blog Post Components
< BlogPosts />
Displays a list of blog posts and provides actions for editing, deleting, and updating draft and featured statuses.
BlogPosts
Props
Name | Type | Description |
---|---|---|
posts | array | An array of blog post data to be displayed in the table. |
< BlogPostsHeader />
Displays the header for the Blog Posts page, including a button to add a new blog post if there are existing posts.
BlogPostsHeader
Props
Name | Type | Description |
---|---|---|
list | boolean | A boolean indicating whether to display the "Add Post" button. |
< BlogPostForm />
Handles the creation and editing of blog posts.
BlogPostForm
Props
Name | Type | Description |
---|---|---|
edit | boolean | A boolean indicating if the form is in edit mode. |
blogPost | object | The blog post data being edited (if in edit mode). |
categories | array | An array of available blog categories to select from. |
user | object | The user data associated with the blog post. |
Files Page
FilesPage
This page lists all files managed within the system. It renders a list of files with a header containing a title and description.
File Components
< Files />
Manages file uploads and displays uploaded files within tabs categorized by file type (e.g., general files, blog post cover images).
Orders Page
OrdersPage
This page lists all orders managed within the system. Fetches all orders using the getAllOrders
action and renders the Orders
component with the list of orders.
Roles
CreateRolePage
This page provides a form to create a new role. It renders a RoleForm
wrapped in a Page
component.
EditRolePage
This page provides a form to edit an existing role. Fetches the role data using the getRole
action and renders the RoleForm
with the edit
prop.
EditRolePage
Props
Name | Type | Description |
---|---|---|
params | object | Contains the id of the role to be edited. |
RolesPage
This page lists all roles managed within the system. Fetches all roles using the getAllRoles
action and renders the Roles
component with the list of roles.
RolePermissionsPage
This page manages the permissions assigned to a specific role. Fetches the role permissions using the getRolePermissions
action and the role details using the getRole
action then renders the Permissions
component with the edit
prop.
RolePermissionsPage
Props
Name | Type | Description |
---|---|---|
params | object | Contains the id of the role for which permissions are being managed. |
Role Components
< Roles />
Displays a list of roles and provides actions for managing permissions, editing, and deleting roles.
Roles
Props
Name | Type | Description |
---|---|---|
roles | array | An array of role data to be displayed in the table. |
< RolesHeader />
Displays the header for the Roles page, including a button to add a new role if there are existing roles.
RolesHeader
Props
Name | Type | Description |
---|---|---|
list | boolean | A boolean indicating whether to display the "Add Role" button. |
< RoleForm />
Handles the creation and editing of roles.
RoleForm
Props
Name | Type | Description |
---|---|---|
edit | boolean | A boolean indicating if the form is in edit mode. |
role | object | The role data being edited (if in edit mode). |
Stories Page
CreateStoryPage
This page provides a form to create a new story. It renders a StoryForm
wrapped in a Page
component.
EditStoryPage
This page provides a form to edit an existing story. Fetches the story data using the getStory
action and renders the StoryForm
with the edit
prop.
EditStoryPage
Props
Name | Type | Description |
---|---|---|
params | object | Contains the id of the story to be edited. |
StoriesPage
This page lists all stories managed within the system. Fetches all stories using the getAllStories
action and renders the Stories
component with the list of stories.
Story Components
< Stories />
Displays a list of stories and provides actions for editing and deleting stories.
Stories
Props
Name | Type | Description |
---|---|---|
stories | array | An array of story data to be displayed in the table. |
< StoriesHeader />
Displays the header for the Stories page, including a button to add a new story if there are existing stories.
StoriesHeader
Props
Name | Type | Description |
---|---|---|
list | boolean | A boolean indicating whether to display the "Add Story" button. |
< StoryForm />
Handles the creation and editing of stories.
StoryForm
Props
Name | Type | Description |
---|---|---|
edit | boolean | A boolean indicating if the form is in edit mode. |
story | object | The story data being edited (if in edit mode). |
Users Page
UsersPage
This page lists all users managed within the system. Fetches all users using the getAllUsers
action and renders the Users
component with the list of users.
User Components
< Users />
Displays a list of users within the system.
Users
Props
Name | Type | Description |
---|---|---|
users | array | An array of user data to be displayed in the table. |
Admin Pages
AdminPage
The main admin dashboard page, displays a greeting and basic information about the logged-in admin user. Fetches the authenticated user's data using the getSupabaseUser
action and displays a personalized greeting based on the time of day and the user's name.
AdminNotFound
The 404 error page for the admin panel. Displays a large "404" message indicating that the requested page was not found.
< ProtectedLayout />
The ProtectedLayout
component ensures that only authenticated users can access certain parts of the admin panel. If the user is not authenticated, they are redirected to the sign-in page. Fetches the authenticated user's data using the getSupabaseUser
action and redirects the user to the sign-in page if they are not authenticated..
ProtectedLayout
Props
Name | Type | Description |
---|---|---|
children | ReactNode | The content to be displayed if the user is authenticated. |
Setup Component's Needs
To ensure your admin panel functions correctly with Supabase, follow these steps:
-
Sign Up or Log In to Supabase
- Go to Supabase and sign up or log in.
-
Create a New Supabase Project
- In the Supabase dashboard, create a new project. You'll receive an
API URL
and anAPI Key
for your project.
- In the Supabase dashboard, create a new project. You'll receive an
-
Configure Environment Variables
- In the root of your Next.js project, create or update your
.env.local
file. Add the following environment variables and replace the placeholders with your actual Supabase details:
- In the root of your Next.js project, create or update your
4.Set Up Row Level Security (RLS)
- Use Supabase's Row Level Security (RLS) policies to restrict access to certain data based on user roles. This can be configured directly in the Supabase dashboard under your project's settings.
- RLS ensures that only users with appropriate roles (like admin) can access or modify specific data.
How to Do Guides
How to Add New CRUD Functionality to the Admin Panel
Step 1: Define the Entity
-
Identify the Entity: Determine the name and structure of the new entity (e.g. Product, Story, BlogCategory).
-
Create Database Schema: Define the database schema for the new entity using Prisma. Add a new model to your
schema.prisma
file.
Here is an example:
Step 2: Create Actions
Create server-side actions to handle the CRUD operations for the new entity.
- Create Action (
create<Entity>.js
): This action will handle the creation of a new entity.
Example: createStory.js
- Read Action (
get<Entity>.js
):
This action will handle reading a single entity by its ID.
Example: getStory.js
- Update Action (
update<Entity>.js
):
This action will handle updating an existing entity.
Example: updateStory.js
- Delete Action (
delete<Entity>.js
):
This action will handle deleting an entity by its ID.
Example: deleteStory.js
- List Action (
getAll<Entity>s.js
): This action will handle listing all instances of the entity. Example:getAllStories.js
Step 3: Create Components
Create React components for displaying, editing, and managing the new entity within the admin panel.
-
Form Component (
<Entity>Form.js
): This component handles creating and editing the entity. Example:StoryForm.js
-
List Component (
<Entity>s.js
): This component lists all instances of the entity and provides actions for editing and deleting. Example:Stories.js
-
Header Component (
<Entity>sHeader.js
): This component provides a header with actions like adding a new entity. Example:StoriesHeader.js
Step 4: Create Admin Pages
Create the Next.js pages for managing the CRUD operations.
-
Create Page (
Create<Entity>Page.js
): Handles the creation of a new entity using the form component. Example:CreateStoryPage.js
-
Edit Page (
Edit<Entity>Page.js
): Handles editing an existing entity using the form component. Example:EditStoryPage.js
-
List Page (
<Entity>sPage.js
): Displays a list of entities using the list component. Example:StoriesPage.js
Step 5: Update Constants
- Update your constants to include the new entity.
Example: Update Stories (
stories.js
):
- Update Permissions (
permissions.js
):
Step 6: Update Navigation
Update the admin panel navigation to include the new entity.
- Update Admin Navigation (
adminNav.js
): Add a new menu item for the new entity.
Step 7: Seed Data
Create and run seed data scripts to populate the database with initial data for testing.
- Seed Script (
seed.js
):
Here is an example for 'Story' entity: