Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,087 changes: 971 additions & 116 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,34 @@
"preview": "vite preview"
},
"dependencies": {
"@floating-ui/react": "^0.27.15",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.12",
"@tailwindcss/vite": "^4.1.6",
"@tiptap/pm": "^3.1.0",
"@tiptap/react": "^3.1.0",
"@tiptap/starter-kit": "^3.1.0",
"axios": "^1.11.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dotenv": "^17.2.1",
"input-otp": "^1.4.2",
"lodash.throttle": "^4.1.1",
"lucide-react": "^0.510.0",
"moment": "^2.30.1",
"next-themes": "^0.4.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^5.1.0",
"react-router": "^7.6.0",
"react-router-dom": "^7.7.1",
"recoil": "^0.7.7",
Expand Down
1 change: 1 addition & 0 deletions public/user.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 27 additions & 7 deletions src/components/dash-navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BookOpen, User } from "lucide-react";
import { BookOpen } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand All @@ -7,8 +7,22 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ModeToggle } from "./mode-toggle";
import { useAdminData } from "@/store/hooks/useAdminData";
import { Skeleton } from "./ui/skeleton";
import { Link } from "react-router-dom";

export const DashboardHeader = () => {
const { adminInfo, loading, error } = useAdminData();
const userInfo = adminInfo?.isUserExist;

if (loading)
return (
<div className="flex items-center gap-3 flex-1 space-y-1">
<Skeleton className="h-9 w-full" />
</div>
);

if (error) return <div>Error loading admin data.</div>;
return (
<header className="flex items-center justify-between p-4 lg:px-6 bg-secondary border-b border-border">
{/* Student Portal Title */}
Expand All @@ -18,24 +32,30 @@ export const DashboardHeader = () => {
</a>

{/* Header Actions */}
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 ">
<Button variant="ghost" size="icon" className="hidden sm:flex">
<ModeToggle />
</Button>

<DropdownMenu>
<DropdownMenuTrigger asChild>
<DropdownMenuTrigger>
<Button
variant="ghost"
size="icon"
className="rounded-full shadow-sm border"
className="rounded-full shadow-sm border p-2"
asChild
>
<User className="h-5 w-5" />
<img
src={userInfo?.profilepic || "./user.svg"}
className="size-8 rounded-full dark:text-secondary"
/>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48">
<DropdownMenuItem>John Dow</DropdownMenuItem>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>{userInfo.firstname}</DropdownMenuItem>
<DropdownMenuItem>
<Link to="/setting">Profile</Link>
</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>
Expand Down
2 changes: 1 addition & 1 deletion src/components/dashboard-welcome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const DashboardWelcome = () => {
<div className="bg-special rounded-lg p-4 lg:p-6 flex items-center justify-between w-full">
<div className="flex items-center gap-3 flex-1">
<img
src={userInfo?.profilepic || "./logo.svg"}
src={userInfo?.profilepic || "./user.svg"}
className="h-16 w-16 rounded-full dark:text-secondary"
/>

Expand Down
3 changes: 2 additions & 1 deletion src/components/mode-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { useTheme } from "@/components/theme-provider";
export function ModeToggle() {
const { setTheme } = useTheme();


return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<DropdownMenuTrigger>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/setting-profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const SettingProfile = () => {
<User className="size-7" />
) : (
<img
src={userInfo?.profilepic || "./logo.svg"}
src={userInfo?.profilepic || "./user.svg"}
className="h-16 w-16 rounded-full dark:text-secondary"
/>
)}
Expand Down
46 changes: 46 additions & 0 deletions src/components/ui/popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"

import { cn } from "@/lib/utils"

function Popover({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
return <PopoverPrimitive.Root data-slot="popover" {...props} />
}

function PopoverTrigger({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
}

function PopoverContent({
className,
align = "center",
sideOffset = 4,
...props
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
return (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
data-slot="popover-content"
align={align}
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
)
}

function PopoverAnchor({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
}

export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
26 changes: 26 additions & 0 deletions src/components/ui/separator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"

import { cn } from "@/lib/utils"

function Separator({
className,
orientation = "horizontal",
decorative = true,
...props
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
data-slot="separator"
decorative={decorative}
orientation={orientation}
className={cn(
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
className
)}
{...props}
/>
)
}

export { Separator }
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand Down Expand Up @@ -113,7 +115,7 @@ const CreateCourse = () => {
<Label htmlFor="department">Department</Label>
<Select
value={createCourse.department}
onValueChange={(value) =>
onValueChange={(value: string) =>
SelectHandler("department", value, setCreateCourse)
}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand All @@ -14,14 +16,14 @@ import axios from "axios";
import { Edit } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import type { CourseData, DepartmentData, EditCourseProps } from "@/types";
import type { CourseData, DepartmentData, EditCourseData } from "@/types";
import { courses } from "../../../store/atoms/academics/courses";
import { useRecoilRefresher_UNSTABLE } from "recoil";
import { useDepartmentData } from "@/store/hooks/academics/use-department-data";

const base_api = import.meta.env.VITE_SERVER_BASE_URL;

const EditCourse = ({ course }: EditCourseProps) => {
const EditCourse = ({ course }: EditCourseData) => {
const { departmentInfo } = useDepartmentData();
const refreshCourse = useRecoilRefresher_UNSTABLE(courses);

Expand Down Expand Up @@ -109,7 +111,7 @@ const EditCourse = ({ course }: EditCourseProps) => {
<Label htmlFor="department">Department</Label>
<Select
value={editingCourse.department}
onValueChange={(value) =>
onValueChange={(value: string) =>
SelectHandler("department", value, setEditingCourse)
}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import { useCoursesData } from "@/store/hooks/academics/use-courses-data";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand All @@ -7,13 +9,13 @@ import axios from "axios";
import { Edit } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import type { DepartmentData, EditDepartmentProps } from "@/types";
import type { DepartmentData, EditDepartmentData } from "@/types";
import { department } from "../../../store/atoms/academics/department";
import { useRecoilRefresher_UNSTABLE } from "recoil";

const base_api = import.meta.env.VITE_SERVER_BASE_URL;

const EditDepartment = ({ departmentInfo }: EditDepartmentProps) => {
const EditDepartment = ({ departmentInfo }: EditDepartmentData) => {
const refreshDepartment = useRecoilRefresher_UNSTABLE(department);

const [editingDepartment, setEditingDepartment] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { useDepartmentData } from "@/store/hooks/academics/use-department-data";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand Down Expand Up @@ -125,7 +127,7 @@ const CreatePrograms = () => {
<Label htmlFor="department">Department</Label>
<Select
value={createProgram.departmentId}
onValueChange={(value) =>
onValueChange={(value:string) =>
SelectHandler("departmentId", value, setCreateProgram)
}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand All @@ -14,15 +16,15 @@ import axios from "axios";
import { Edit } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import type { DepartmentData, EditProgramProps, ProgramData } from "@/types";
import type { DepartmentData, EditProgramData, ProgramData } from "@/types";
import { programs } from "../../../store/atoms/academics/programs";
import { useRecoilRefresher_UNSTABLE } from "recoil";
import { useDepartmentData } from "@/store/hooks/academics/use-department-data";
import { Textarea } from "@/components/ui/textarea";

const base_api = import.meta.env.VITE_SERVER_BASE_URL;

const EditProgram = ({ program }: EditProgramProps) => {
const EditProgram = ({ program }: EditProgramData) => {
const { departmentInfo } = useDepartmentData();
const refreshCourse = useRecoilRefresher_UNSTABLE(programs);

Expand Down Expand Up @@ -125,7 +127,7 @@ const EditProgram = ({ program }: EditProgramProps) => {
value={
editingProgram.department?.id || editingProgram.departmentId
}
onValueChange={(value) =>
onValueChange={(value:string) =>
SelectHandler("department", value, setEditingProgram)
}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use client";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
'use client'


import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client'

import UseModel from "@/components/models/useModel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
Expand All @@ -14,13 +16,13 @@ import axios from "axios";
import { Edit } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import type { EditSemesterProps, SemesterData } from "@/types";
import type { EditSemesterData, SemesterData } from "@/types";
import { useRecoilRefresher_UNSTABLE } from "recoil";
import { semester } from "@/store/atoms/academics/semester";

const base_api = import.meta.env.VITE_SERVER_BASE_URL;

const EditSemester = ({ semesterInfo }: EditSemesterProps) => {
const EditSemester = ({ semesterInfo }: EditSemesterData) => {
const refreshSemester = useRecoilRefresher_UNSTABLE(semester);

const [editingSemester, setEditingSemester] = useState<SemesterData | null>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
'use client'


import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
Expand Down
Loading