Skip to content

Commit

Permalink
feat/chore: Improve and enhance tutor page and make it responsive (#161)
Browse files Browse the repository at this point in the history
* feat: improve tutor dashboard page and make it responsive

* updates
  • Loading branch information
martinvibes authored Feb 25, 2025
1 parent e64a34d commit ab6ba2d
Show file tree
Hide file tree
Showing 29 changed files with 760 additions and 1,571 deletions.
1,040 changes: 0 additions & 1,040 deletions bun.lock

This file was deleted.

2 changes: 0 additions & 2 deletions src/app/dashboard/tutor/component/Addcourse.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import React, { useState } from "react";
import { PlusIcon } from "lucide-react";
import CreateCourseModal from "@/app/dashboard/tutor/component/Create-Course-Modal";
Expand All @@ -21,7 +20,6 @@ export const Addcourse = () => {
<PlusIcon className="w-[16px] h-[16px]" /> CREATE NEW COURSE
</button>

{/* Render modal only if isModalOpen is true */}
{isModalOpen && (
<CreateCourseModal
isOpen={isModalOpen}
Expand Down
96 changes: 55 additions & 41 deletions src/app/dashboard/tutor/component/CourseCard.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,64 @@
import {Edit2Icon} from "lucide-react";
import { Edit2Icon } from "lucide-react";

type courseProps = {
id: number;
banner: string;
title: string;
enrollment: number;
rating: number;
published: boolean;
videosAvailable: boolean;
id: number;
banner: string;
title: string;
enrollment: number;
rating: number;
published: boolean;
videosAvailable: boolean;
};
interface courseCardprops {
courses: courseProps;
courses: courseProps;
}

const CourseCard: React.FC<courseCardprops> = ({courses}) => {
return (
<div className=" h-[218px] bg-[#161716] p-[24px] rounded-[8px] flex gap-[15px] ">
<section className="w-[300px] h-[170px] bg-slate-500/20 rounded-[8px]">
{/* <Image src={courses.banner} width={100} height={100} alt="course-banner" className="w-full h-full" /> */}
</section>
<section className="flex-grow flex flex-col gap-[15px]">
<div className="flex justify-between">
<div className="flex flex-col gap-3">
<h3 className="font-[600] text-[#FCFCFC] text-[18px]">{courses.title}</h3>
<h4 className="font-[500] text-[#8DCAD7CC] text-[14px]">{courses.videosAvailable ? "Video/Note guide available" : ""}</h4>
</div>
<div className="w-[82px] h-[32px] rounded-[48px] px-[14px] py-[4px] bg-[#2D2E2D] text-[12px] font-[500] flex justify-center items-center">
{courses.published ? "published" : "draft"}
</div>
</div>
<div className="flex justify-between ">
<div className="text-[#6E6E6E] font-[500] text-[14px]">
Enrolment: <span className="text-white"> {courses.enrollment} Learners</span>
</div>
<div className="text-[#6E6E6E] font-[500] text-[14px]">
Rating: <span className="text-white">{courses.rating <= 0 ? "N/A" : `${courses.rating}/5`}</span>
</div>
</div>
<button className="w-[110px] h-[30px] border-[#2F302F] border-[1px] border-solid rounded-[8px] font-[400] text-[12px] flex justify-center items-center gap-2">
{" "}
<Edit2Icon className="w-[14px] h-[14px]" />
Edit Course
</button>
</section>
</div>
);
const CourseCard: React.FC<courseCardprops> = ({ courses }) => {
return (
<div className="bg-[#161716] p-3 sm:p-4 md:p-[24px] rounded-[8px] flex flex-col sm:flex-row gap-3 sm:gap-[15px]">
<section className="w-full sm:w-[150px] md:w-[200px] lg:w-[300px] h-[120px] sm:h-[150px] md:h-[170px] bg-slate-500/20 rounded-[8px] flex-shrink-0">
{/* <Image src={courses.banner} width={100} height={100} alt="course-banner" className="w-full h-full object-cover rounded-[8px]" /> */}
</section>

<section className="flex-grow flex flex-col gap-2 sm:gap-[15px]">
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-2 sm:gap-0">
<div className="flex flex-col gap-1 sm:gap-3">
<h3 className="font-[600] text-[#FCFCFC] text-base sm:text-[18px] line-clamp-2">
{courses.title}
</h3>
<h4 className="font-[500] text-[#8DCAD7CC] text-xs sm:text-[14px]">
{courses.videosAvailable ? "Video/Note guide available" : ""}
</h4>
</div>
<div className="self-start py-[4px] px-[14px] rounded-[48px] bg-[#2D2E2D] text-[12px] font-[500] flex justify-center items-center">
{courses.published ? "published" : "draft"}
</div>
</div>

<div className="flex flex-col xs:flex-row justify-between gap-1 xs:gap-0">
<div className="text-[#6E6E6E] font-[500] text-xs sm:text-[14px]">
Enrolment:{" "}
<span className="text-white"> {courses.enrollment} Learners</span>
</div>
<div className="text-[#6E6E6E] font-[500] text-xs sm:text-[14px]">
Rating:{" "}
<span className="text-white">
{courses.rating <= 0 ? "N/A" : `${courses.rating}/5`}
</span>
</div>
</div>

{courses.published ? (
""
) : (
<button className="w-[110px] h-[30px] border-[#2F302F] border-[1px] border-solid rounded-[8px] font-[400] text-[12px] flex justify-center items-center gap-2 mt-auto">
<Edit2Icon className="w-[14px] h-[14px]" />
Edit Course
</button>
)}
</section>
</div>
);
};

export default CourseCard;
3 changes: 1 addition & 2 deletions src/app/dashboard/tutor/component/DashboardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import Avatar from "@/public/img/Avatar.png";
import { Button } from "@headlessui/react";
import { DashBoardContext } from "@/app/useContext/dashboardContext";


function Header() {
const { activeSection } = useContext(DashBoardContext);
const { activeSection } = useContext(DashBoardContext);
const pathname = usePathname();
const [isMenuOpen, setIsMenuOpen] = useState(false);

Expand Down
12 changes: 6 additions & 6 deletions src/app/dashboard/tutor/component/DateActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
interface DateActionButtonProps {
label: string;
onClick: () => void;
}
label: string;
onClick: () => void;
}

export function DateActionButton({ label, onClick }: DateActionButtonProps) {
return (
<button
onClick={onClick}
className="w-full px-3 py-3 bg-none border border-[#2D2E2D] hover:bg-[#FFFFFF1A] rounded-3xl transition-colors"
onClick={onClick}
className="w-full px-3 py-3 bg-none border border-[#2D2E2D] hover:bg-[#FFFFFF1A] rounded-3xl transition-colors"
>
{label}
{label}
</button>
);
}
7 changes: 4 additions & 3 deletions src/app/dashboard/tutor/component/EarningStatCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from 'react'
import { ReactNode } from "react";

interface StatCardProps {
icon: ReactNode;
Expand All @@ -7,10 +7,11 @@ interface StatCardProps {
bgCol?: string;
}

export function EarningStatCard({icon, value, label, bgCol}: StatCardProps) {
export function EarningStatCard({ icon, value, label, bgCol }: StatCardProps) {
return (
<div
className={` bg-[#1E1E1E] cursor-pointer hover:bg-[#FFFFFF1A] p-6 rounded-lg`}>
className={` bg-[#1E1E1E] cursor-pointer hover:bg-[#FFFFFF1A] p-6 rounded-lg`}
>
<div className="flex min-h-[64px] items-center justify-start gap-3 pr-20">
<div className="min-h-[64px] ">
<div
Expand Down
135 changes: 96 additions & 39 deletions src/app/dashboard/tutor/component/PaymentHistoryTable.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,104 @@
import React from 'react'
import { Copy } from "lucide-react";
import React from "react";
import { Copy } from "lucide-react";

interface PaymentHistoryTableProps {
transactions: {
id: number;
transactionId: string;
amount: string;
date: string;
}[];
}
transactions: {
id: number;
transactionId: string;
amount: string;
date: string;
}[];
}

export function PaymentHistoryTable({ transactions }: PaymentHistoryTableProps) {
export function PaymentHistoryTable({
transactions,
}: PaymentHistoryTableProps) {
return (
<div className="w-full overflow-hidden rounded-lg mb-6">
<table className="w-full text-center border-collapse">
<thead >
<tr className=" text-gray-400 bg-[#1E1E1E] ">
<th className="py-4">SN</th>
<th className="py-4">Transaction ID</th>
<th className="py-4">Amount</th>
<th className="py-4">Date</th>
</tr>
</thead>
<tbody>
{transactions.map((tx) => (
<tr key={tx.id} className="border-b border-gray-700 ">
<td className="py-6">{tx.id}</td>
<td className="py-6 flex items-center justify-center gap-3 text-center">
{tx.transactionId}
<button
onClick={() => navigator.clipboard.writeText(tx.transactionId)}
className="text-gray-400 hover:text-white"
title="Copy Transaction ID"
>
<Copy size={20}/>
</button>
</td>
<td className="py-6">{tx.amount}</td>
<td className="py-6">{tx.date}</td>
<div className="w-full overflow-x-auto rounded-lg mb-6">
{/* Desktop and Tablet View */}
<table className="w-full text-center border-collapse min-w-[650px]">
<thead>
<tr className="text-gray-400 bg-[#1E1E1E]">
<th className="py-3 sm:py-4 px-2 text-sm sm:text-base">SN</th>
<th className="py-3 sm:py-4 px-2 text-sm sm:text-base">
Transaction ID
</th>
<th className="py-3 sm:py-4 px-2 text-sm sm:text-base">Amount</th>
<th className="py-3 sm:py-4 px-2 text-sm sm:text-base">Date</th>
</tr>
</thead>
<tbody>
{transactions.map((tx) => (
<tr
key={tx.id}
className="border-b border-gray-700 hover:bg-[#2a2a2a]"
>
<td className="py-4 sm:py-6 px-2 text-sm sm:text-base">
{tx.id}
</td>
<td className="py-4 sm:py-6 px-2 text-sm sm:text-base">
<div className="flex items-center justify-center gap-2 sm:gap-3">
<span className="truncate max-w-[150px] sm:max-w-none">
{tx.transactionId}
</span>
<button
onClick={() =>
navigator.clipboard.writeText(tx.transactionId)
}
className="text-gray-400 hover:text-white flex-shrink-0"
title="Copy Transaction ID"
>
<Copy size={16} className="sm:w-5 sm:h-5" />
</button>
</div>
</td>
<td className="py-4 sm:py-6 px-2 text-sm sm:text-base">
{tx.amount}
</td>
<td className="py-4 sm:py-6 px-2 text-sm sm:text-base">
{tx.date}
</td>
</tr>
))}
</tbody>
</table>

{/* Mobile Card View - Visible only on very small screens */}
{/* <div className="sm:hidden mt-4 space-y-4">
{transactions.map((tx) => (
<div key={tx.id} className="bg-[#1E1E1E] rounded-lg p-4 space-y-3">
<div className="flex justify-between">
<span className="text-gray-400">SN</span>
<span>{tx.id}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-400">Transaction ID</span>
<div className="flex items-center gap-2">
<span className="truncate max-w-[120px]">
{tx.transactionId}
</span>
<button
onClick={() =>
navigator.clipboard.writeText(tx.transactionId)
}
className="text-gray-400 hover:text-white"
title="Copy Transaction ID"
>
<Copy size={16} />
</button>
</div>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Amount</span>
<span>{tx.amount}</span>
</div>
<div className="flex justify-between">
<span className="text-gray-400">Date</span>
<span>{tx.date}</span>
</div>
</div>
))}
</tbody>
</table>
</div>
</div> */}
</div>
);
}
18 changes: 15 additions & 3 deletions src/app/dashboard/tutor/component/QuickActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import { DashBoardContext } from "@/app/useContext/dashboardContext";
import { useContext } from "react";

interface QuickActionButtonProps {
label: string;
onClick: () => void;
sectionName: string;
}

export function QuickActionButton({ label, onClick }: QuickActionButtonProps) {
export function QuickActionButton({
label,
sectionName,
}: QuickActionButtonProps) {
const { setActiveSection: onSectionChange } = useContext(DashBoardContext);

const handleClick = () => {
onSectionChange(sectionName);
};

return (
<button
onClick={onClick}
onClick={handleClick}
className="w-full px-6 py-3 bg-none border border-[#2D2E2D] hover:bg-[#FFFFFF1A] rounded-lg transition-colors"
>
{label}
Expand Down
2 changes: 1 addition & 1 deletion src/app/dashboard/tutor/component/StatCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function StatCard({ icon, value, label, bgCol }: StatCardProps) {

<div>
<p className="text-2xl font-bold mb-1 text-[30px]">{value}</p>
<p className="text-gray-400 text-[14px]">{label}</p>
<p className="text-gray-400 text-[13px] md:text-[14px]">{label}</p>
</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/app/dashboard/tutor/component/TutorDashboardSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ function NavItem({ icon, label, active = false, onClick }: NavItemProps) {
}

export function Sidebar() {
const { activeSection, setActiveSection: onSectionChange } =
useContext(DashBoardContext);
const { activeSection, setActiveSection: onSectionChange } =
useContext(DashBoardContext);
return (
<aside className="w-64 border-r min-h-[90vh] bg-[#161716] border-gray-800 overflow-y-auto">
<div className="p-4 h-[100%] overflow-y-auto scrollbar-hide scroll-smooth">
Expand Down Expand Up @@ -105,7 +105,7 @@ export function Sidebar() {
</nav>
</div>

<div className="absolute bottom-0 w-64 border-t border-gray-800">
<div className="absolute -bottom-20 w-64 border-t border-gray-800">
<NavItem
icon={<Headset size={20} />}
label="Support"
Expand Down
Loading

0 comments on commit ab6ba2d

Please sign in to comment.