Skip to content

Commit

Permalink
Merge pull request #70 from Informatik-Projekt-Kurs/IPK-260-Company-B…
Browse files Browse the repository at this point in the history
…rowsing-Page

Ipk 260 company browsing page
  • Loading branch information
bencodes07 authored Oct 24, 2024
2 parents e2e3665 + 59afa4c commit 2645397
Show file tree
Hide file tree
Showing 20 changed files with 948 additions and 178 deletions.
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

0 comments on commit 2645397

Please sign in to comment.