Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ipk 260 company browsing page #70

Merged
merged 6 commits into from
Oct 24, 2024
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
99 changes: 99 additions & 0 deletions src/app/company/dashboard/bookings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"use client";
import { Input } from "@/components/ui/input";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { extractNameInitials } from "@/lib/utils";
import React from "react";
import { useRouter } from "next/navigation";
import { deleteToken } from "@/lib/authActions";
import Loader from "@/components/layout/Loader";
import { useCompany } from "@/components/dashboard/CompanyContext";

export default function Page() {
const { user, loading, companyLoading, company } = useCompany();
const router = useRouter();

const logout = async () => {
try {
await deleteToken();
window.location.reload();
} catch (logoutError) {
console.error("Logout failed", logoutError);
throw logoutError;
}
};

if (loading || companyLoading) return <Loader />;

return (
<div className="flex h-[calc(100%-32px)] flex-col items-start justify-start p-8 px-6">
<header className="flex w-full flex-row items-center justify-between">
<h1 className="m-4 font-medium text-muted-foreground md:text-2xl">
{company?.getCompany.name} (ID: {company?.getCompany.id})
</h1>
<div className="flex items-center gap-x-6">
<Input className="w-[320px]" placeholder="Search"></Input>
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild className={"mr-4"}>
<Button variant="ghost" className="relative size-8 rounded-full">
<Avatar className="size-10">
<AvatarFallback className={"bg-primary"}>{extractNameInitials(user?.name)}</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align={"end"} className={"w-56 border-border"}>
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">{user?.name}</p>
<p className="text-xs leading-none text-muted-foreground">{user?.email}</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => {
router.push("/dashboard/settings");
}}>
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={logout} className={"text-red-500"}>
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>

<div className="mt-8 flex h-[600px] w-full flex-col rounded-[20px] px-12">
<div className={"mt-6 flex h-[200px] w-full items-center justify-between"}>
<div className={"flex flex-row items-center justify-center"}>
<div
className={
"flex size-[200px] items-center justify-center rounded-full bg-primary text-6xl font-medium text-foreground"
}>
{extractNameInitials(company?.getCompany.name)}
</div>
<div className={"ml-12 flex flex-col"}>
<h1 className={"text-4xl font-semibold"}>{company?.getCompany.name}</h1>
</div>
</div>
</div>
<p className={"mt-10 text-muted-foreground"}>
{company?.getCompany.description !== "" ? (
company?.getCompany.description
) : (
<i>This company has not provided a description</i>
)}
</p>
</div>
</div>
);
}
120 changes: 120 additions & 0 deletions src/app/company/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"use client";
import { Button } from "@/components/ui/button";
import { LuBookCopy, LuLayoutDashboard } from "react-icons/lu";
import React, { Suspense, useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { cn, extractNameInitials } from "@/lib/utils";
import Loader from "@/components/layout/Loader";
import { CompanyProvider, useCompany } from "@/components/dashboard/CompanyContext";
import { BriefcaseBusiness, Users } from "lucide-react";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";

function DashboardContent({ children }: { children: React.ReactNode }) {
const { companyLoading, loading, company } = useCompany();
const [active, setActive] = useState<"dashboard" | "bookings" | "users" | "members">("dashboard");
const pathname = usePathname();

useEffect(() => {
// Derive the active state based on the current pathname
if (pathname.includes("/company/dashboard/bookings")) {
setActive("bookings");
} else if (pathname.includes("/company/dashboard/users")) {
setActive("users");
} else if (pathname.includes("/company/dashboard/members")) {
setActive("members");
} else {
setActive("dashboard");
}
}, [pathname]);

return (
<div className="flex w-full flex-col gap-5 pl-8 md:flex-row">
<aside className="hidden lg:block">
<div className="sticky top-8 flex h-[calc(100vh-64px)] flex-row">
<div className="flex h-full w-[80px] flex-col items-center justify-start">
<div
className="absolute mt-10 flex h-16 w-[80px] items-center justify-start rounded-l-md bg-subtle shadow-lg"
style={{ marginTop: 40 }}>
<div className="ml-[8px] h-1/2 w-px bg-primary"></div>
</div>
<div className="mt-12 flex size-12 items-center justify-center rounded-md">
<Link href={"/company/dashboard"}>
<Avatar className="size-10">
<AvatarFallback className={"bg-primary"}>
{extractNameInitials(company?.getCompany.name)}
</AvatarFallback>
</Avatar>
</Link>
</div>
</div>
<div className="flex h-full w-[230px] flex-col items-center justify-start rounded-[20px] border-2 border-primary">
<h1 className="mt-8 text-xl font-bold">{company?.getCompany.name}</h1>
<div className="mt-[35%] flex flex-col items-center justify-start gap-y-4">
<header className="relative left-[-40%] mb-[-6px] text-xs text-muted-foreground">Tools</header>
<Link href={"/company/dashboard"}>
<Button
className={cn(
"w-[168px] justify-start",
active === "dashboard" ? "text-foreground" : "text-muted-foreground"
)}
variant={active === "dashboard" ? "default" : "ghost"}>
<LuLayoutDashboard className="mx-2" size={18} />
Dashboard
</Button>
</Link>
<Link href={"/company/dashboard/bookings"}>
<Button
className={cn(
"w-[168px] justify-start",
active === "bookings" ? "text-foreground" : "text-muted-foreground"
)}
variant={active === "bookings" ? "default" : "ghost"}>
<LuBookCopy className="mx-2" size={18} />
Bookings
</Button>
</Link>
<Link href={"/company/dashboard/users"}>
<Button
className={cn(
"w-[168px] justify-start",
active === "users" ? "text-foreground" : "text-muted-foreground"
)}
variant={active === "users" ? "default" : "ghost"}>
<Users className="mx-2" size={18} />
Users
</Button>
</Link>
<Link href={"/company/dashboard/members"}>
<Button
className={cn(
"w-[168px] justify-start",
active === "members" ? "text-foreground" : "text-muted-foreground"
)}
variant={active === "members" ? "default" : "ghost"}>
<BriefcaseBusiness className="mx-2" size={18} />
Members
</Button>
</Link>
</div>
</div>
</div>
</aside>
<main className="mr-8 mt-8 min-h-[calc(100vh-64px)] w-full rounded-[20px] border-2 border-border">
{loading || companyLoading ? <Loader /> : <Suspense fallback={<Loader />}>{children}</Suspense>}
<footer className="flex h-8 w-full items-center justify-start rounded-b-[20px] bg-primary">
<p className="pl-4 text-sm font-medium text-background">MeetMate</p>
</footer>
</main>
</div>
);
}

// Wrap the dashboard with the UserProvider
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<CompanyProvider>
<DashboardContent>{children}</DashboardContent>
</CompanyProvider>
);
}
99 changes: 99 additions & 0 deletions src/app/company/dashboard/members/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"use client";
import { Input } from "@/components/ui/input";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { extractNameInitials } from "@/lib/utils";
import React from "react";
import { useRouter } from "next/navigation";
import { deleteToken } from "@/lib/authActions";
import Loader from "@/components/layout/Loader";
import { useCompany } from "@/components/dashboard/CompanyContext";

export default function Page() {
const { user, loading, companyLoading, company } = useCompany();
const router = useRouter();

const logout = async () => {
try {
await deleteToken();
window.location.reload();
} catch (logoutError) {
console.error("Logout failed", logoutError);
throw logoutError;
}
};

if (loading || companyLoading) return <Loader />;

return (
<div className="flex h-[calc(100%-32px)] flex-col items-start justify-start p-8 px-6">
<header className="flex w-full flex-row items-center justify-between">
<h1 className="m-4 font-medium text-muted-foreground md:text-2xl">
{company?.getCompany.name} (ID: {company?.getCompany.id})
</h1>
<div className="flex items-center gap-x-6">
<Input className="w-[320px]" placeholder="Search"></Input>
<DropdownMenu modal={false}>
<DropdownMenuTrigger asChild className={"mr-4"}>
<Button variant="ghost" className="relative size-8 rounded-full">
<Avatar className="size-10">
<AvatarFallback className={"bg-primary"}>{extractNameInitials(user?.name)}</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align={"end"} className={"w-56 border-border"}>
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm font-medium leading-none">{user?.name}</p>
<p className="text-xs leading-none text-muted-foreground">{user?.email}</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => {
router.push("/dashboard/settings");
}}>
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={logout} className={"text-red-500"}>
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>

<div className="mt-8 flex h-[600px] w-full flex-col rounded-[20px] px-12">
<div className={"mt-6 flex h-[200px] w-full items-center justify-between"}>
<div className={"flex flex-row items-center justify-center"}>
<div
className={
"flex size-[200px] items-center justify-center rounded-full bg-primary text-6xl font-medium text-foreground"
}>
{extractNameInitials(company?.getCompany.name)}
</div>
<div className={"ml-12 flex flex-col"}>
<h1 className={"text-4xl font-semibold"}>{company?.getCompany.name}</h1>
</div>
</div>
</div>
<p className={"mt-10 text-muted-foreground"}>
{company?.getCompany.description !== "" ? (
company?.getCompany.description
) : (
<i>This company has not provided a description</i>
)}
</p>
</div>
</div>
);
}
Loading