Skip to content

Commit 436e6a1

Browse files
committed
created a new ui for the dashboard
1 parent 20cdd97 commit 436e6a1

File tree

14 files changed

+412
-320
lines changed

14 files changed

+412
-320
lines changed

apps/web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"class-variance-authority": "^0.7.0",
2626
"clsx": "^2.1.1",
2727
"framer-motion": "^11.15.0",
28+
"geist": "^1.5.1",
2829
"lucide-react": "^0.456.0",
2930
"next": "15.5.3",
3031
"next-auth": "^4.24.11",

apps/web/src/app/(main)/dashboard/home/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
2+
import React from "react";
33
import { useProjectTitleStore } from "@/store/useProjectTitleStore";
44
import Dashboard from "../page";
55
import { useProjectsData } from "@/store/useProjectsDataStore";

apps/web/src/app/(main)/dashboard/layout.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,34 @@
11
"use client";
2-
import { DashboardHeader } from "@/components/dashboard/DashboardHeader";
32
import Sidebar from "@/components/dashboard/Sidebar";
43
import FiltersContainer from "@/components/ui/FiltersContainer";
54
import { useFilterStore } from "@/store/useFilterStore";
65
import { useShowSidebar } from "@/store/useShowSidebar";
6+
import { IconWrapper } from "@/components/ui/IconWrapper";
7+
import { Bars3Icon } from "@heroicons/react/24/outline";
78

89
export default function DashboardLayout({
910
children,
1011
}: {
1112
children: React.ReactNode;
1213
}) {
1314
const { showFilters } = useFilterStore();
14-
const { showSidebar } = useShowSidebar();
15+
const { showSidebar, setShowSidebar } = useShowSidebar();
1516
return (
16-
<div className="flex flex-col md:gap-3">
17-
<div className="flex w-full h-16">
18-
<DashboardHeader></DashboardHeader>
19-
</div>
20-
<div className="flex flex-row w-full">
21-
{showFilters && <FiltersContainer></FiltersContainer>}
22-
<aside
23-
className={`w-48 md:w-[40%] xl:w-[20%] ${showSidebar ? "block relative" : "hidden"} xl:block`}
24-
>
25-
<Sidebar></Sidebar>
26-
</aside>
27-
<main className="flex-grow">{children}</main>
17+
<div className="flex w-screen h-screen bg-[#0a0a0b] overflow-hidden">
18+
{showFilters && <FiltersContainer />}
19+
<aside className={`h-full ${!showSidebar && "hidden xl:block"}`}>
20+
<Sidebar />
21+
</aside>
22+
<div className="flex-1 flex flex-col h-full">
23+
<div className="xl:hidden flex items-center h-16 px-4 border-b border-[#1a1a1d]">
24+
<IconWrapper onClick={() => setShowSidebar(true)}>
25+
<Bars3Icon className="size-5 text-ox-purple" />
26+
</IconWrapper>
27+
<h1 className="ml-4 text-lg font-semibold text-ox-white">Opensox</h1>
28+
</div>
29+
<main className="flex-1 h-full overflow-auto">
30+
{children}
31+
</main>
2832
</div>
2933
</div>
3034
);

apps/web/src/app/(main)/dashboard/projects/page.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ import { useRenderProjects } from "@/store/useRenderProjectsStore";
44
import Dashboard from "../page";
55
import { useEffect } from "react";
66
import { useProjectTitleStore } from "@/store/useProjectTitleStore";
7+
import { useProjectsData } from "@/store/useProjectsDataStore";
78

89
const Projects = () => {
910
const { setRenderProjects } = useRenderProjects();
1011
const { setProjectTitle } = useProjectTitleStore();
12+
const { setData } = useProjectsData();
1113

1214
useEffect(() => {
13-
setRenderProjects(false);
14-
setProjectTitle("Projects of the week");
15-
}, [setRenderProjects, setProjectTitle]);
15+
setRenderProjects(true); // Change to true to always render the container
16+
setProjectTitle("Projects");
17+
setData([]); // Clear any existing projects
18+
}, [setRenderProjects, setProjectTitle, setData]);
1619

17-
return <Dashboard></Dashboard>;
20+
return <Dashboard />;
1821
};
1922

2023
export default Projects;

apps/web/src/app/layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { authConfig } from "@/lib/auth/config";
1010
import { SessionWrapper } from "./SessionWrapper";
1111
import SupportDropdown from "@/components/landing-sections/SupportDropdown";
1212
import { TRPCProvider } from "@/providers/trpc-provider";
13+
import { GeistSans } from "geist/font/sans";
1314

1415
const dmReg = localFont({
1516
src: "./fonts/DMMono-Regular.ttf",
@@ -39,7 +40,7 @@ export default async function RootLayout({
3940
return (
4041
<html lang="en" suppressHydrationWarning>
4142
<body
42-
className={`${dmMed.variable} ${dmReg.variable} antialiased bg-background`}
43+
className={`${GeistSans.className} ${dmMed.variable} ${dmReg.variable} antialiased bg-background`}
4344
>
4445
<PostHogProvider>
4546
<ThemeProvider

apps/web/src/components/dashboard/DashboardContainer.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,36 @@ import { useLoading } from "@/store/useLoadingStore";
77
import { useProjectsNotFoundStore } from "@/store/useProjectsFoundStore";
88
import { ErrMsg } from "../ui/ErrMsg";
99
import SpinnerElm from "../ui/SpinnerElm";
10+
import { usePathname } from "next/navigation";
1011

1112
export default function DashboardContainer() {
1213
const { renderProjects } = useRenderProjects();
1314
const { data } = useProjectsData();
1415
const { loading } = useLoading();
1516
const { projectsNotFound } = useProjectsNotFoundStore();
17+
const pathname = usePathname();
18+
19+
const isProjectsPage = pathname === "/dashboard/projects";
20+
1621
return (
17-
<div
18-
className={`h-[80vh] md:h-[88vh] rounded-lg mx-1 md:mx-4 bg-ox-black-1 border border-ox-gray ${!renderProjects ? "flex items-center justify-center" : ""}`}
19-
>
20-
<div className={`max-h-full ${!loading ? "overflow-y-scroll" : ""}`}>
21-
{renderProjects && (
22+
<div className={`min-h-[calc(100vh-64px)] ${isProjectsPage ? "flex items-center justify-center" : ""}`}>
23+
<div className={`w-full ${!loading ? "h-full" : ""}`}>
24+
{renderProjects && !loading && (
2225
<ProjectsContainer projects={data}></ProjectsContainer>
2326
)}
2427
{loading && (
25-
<SpinnerElm text={"loading cool projects for you..."}></SpinnerElm>
26-
)}
27-
{projectsNotFound && (
28-
<ErrMsg
29-
text={
30-
"No projects were found matching the selected filters. Please adjust the filters and try again."
31-
}
32-
></ErrMsg>
28+
<div className="flex items-center justify-center h-full">
29+
<SpinnerElm text={"loading cool projects for you..."}></SpinnerElm>
30+
</div>
3331
)}
34-
{!renderProjects && !loading && (
35-
<ErrMsg
36-
text={"Click on 'Find Projects' to see the magic."}
37-
></ErrMsg>
32+
{projectsNotFound && !loading && (
33+
<div className="flex items-center justify-center h-full">
34+
<ErrMsg
35+
text={
36+
"No projects were found matching the selected filters. Please adjust the filters and try again."
37+
}
38+
></ErrMsg>
39+
</div>
3840
)}
3941
</div>
4042
</div>
Lines changed: 108 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import { Badge } from "@/components/ui/badge";
4+
import { Button } from "@/components/ui/button";
45
import {
56
Table,
67
TableBody,
@@ -12,6 +13,9 @@ import {
1213
import { useProjectTitleStore } from "@/store/useProjectTitleStore";
1314
import { DashboardProjectsProps } from "@/types";
1415
import Image from "next/image";
16+
import { useFilterStore } from "@/store/useFilterStore";
17+
import { usePathname } from "next/navigation";
18+
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
1519

1620
type ProjectsContainerProps = {
1721
projects: DashboardProjectsProps[];
@@ -62,95 +66,122 @@ const getColor = (color: string): string => {
6266
return _color;
6367
};
6468

69+
const tableColumns = [
70+
"Project",
71+
"Issues",
72+
"Language",
73+
"Popularity",
74+
"Stage",
75+
"Competition",
76+
"Activity",
77+
];
78+
6579
export default function ProjectsContainer({
6680
projects,
6781
}: ProjectsContainerProps) {
82+
const pathname = usePathname();
83+
const { projectTitle } = useProjectTitleStore();
84+
const { setShowFilters } = useFilterStore();
85+
6886
const handleClick = (link: string) => {
6987
window.open(link, "_blank");
7088
};
71-
const { projectTitle } = useProjectTitleStore();
72-
const tableColums = [
73-
"Project",
74-
"Issues",
75-
"Language",
76-
"Popularity",
77-
"Stage",
78-
"Competition",
79-
"Activity",
80-
];
89+
90+
const isProjectsPage = pathname === "/dashboard/projects";
91+
8192
return (
82-
<div className="w-full rounded-lg p-2 sm:p-4">
83-
<div className="flex items-center justify-between pb-1">
84-
<h2 className="text-xs sm:text-sm md:text-md font-semibold text-white">
93+
<div className="w-full p-6 sm:p-8">
94+
<div className="flex items-center justify-between pb-6">
95+
<h2 className="text-xl sm:text-2xl md:text-3xl font-semibold text-white tracking-tight">
8596
{projectTitle}
8697
</h2>
98+
{isProjectsPage && (
99+
<Button
100+
className="font-semibold text-white bg-ox-purple text-sm sm:text-base h-10 sm:h-11 px-5 sm:px-6 hover:bg-white-500 rounded-md"
101+
onClick={() => setShowFilters(true)}
102+
>
103+
Find projects
104+
</Button>
105+
)}
87106
</div>
88-
<div className="rounded-lg border bg-ox-black-2 border-ox-gray border w-full overflow-x-auto">
89-
<Table className="w-full">
90-
<TableHeader className="w-full border">
91-
<TableRow className="w-full border-ox-gray border-b">
92-
{tableColums.map((name, index) => (
93-
<TableHead
94-
key={index}
95-
className={`flex-1 text-center text-zinc-400 font-semibold text-ox-purple
96-
text-[12px] sm:text-sm`}
97-
>
98-
{name}
99-
</TableHead>
100-
))}
101-
</TableRow>
102-
</TableHeader>
103-
<TableBody>
104-
{projects.map((project) => (
105-
<TableRow
106-
key={project.id}
107-
className="border-ox-gray border-y cursor-pointer"
108-
onClick={() => {
109-
handleClick(project.url);
110-
}}
111-
>
112-
<TableCell className="flex items-center gap-1 p-1 sm:p-2">
113-
<div className="rounded-full overflow-hidden inline-block h-4 w-4 sm:h-6 sm:w-6 border">
114-
<Image
115-
src={project.avatarUrl}
116-
className="w-full h-full object-cover"
117-
alt={project.name}
118-
width={10}
119-
height={10}
120-
/>
121-
</div>
122-
<TableCell className="text-white text-[10px] sm:text-xs text-ox-white font-semibold">
123-
{project.name}
124-
</TableCell>
125-
</TableCell>
126-
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white p-1 sm:p-2">
127-
{project.totalIssueCount}
128-
</TableCell>
129-
<TableCell className="text-center p-1 sm:p-2">
130-
<Badge
131-
variant="secondary"
132-
className={`${getColor(project.primaryLanguage)} text-[10px] sm:text-xs`}
107+
{projects && projects.length > 0 ? (
108+
<div className="w-full overflow-x-auto bg-[#15161a] border border-[#1a1a1d] rounded-lg">
109+
<Table className="w-full">
110+
<TableHeader className="w-full border">
111+
<TableRow className="w-full border-[#1a1a1d] border-b">
112+
{tableColumns.map((name, index) => (
113+
<TableHead
114+
key={index}
115+
className={`flex-1 text-center font-semibold text-ox-purple text-[12px] sm:text-sm`}
133116
>
134-
{project.primaryLanguage}
135-
</Badge>
136-
</TableCell>
137-
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold p-1 sm:p-2">
138-
{project.popularity}
139-
</TableCell>
140-
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
141-
{project.stage}
142-
</TableCell>
143-
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
144-
{project.competition}
145-
</TableCell>
146-
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
147-
{project.activity}
148-
</TableCell>
117+
{name}
118+
</TableHead>
119+
))}
149120
</TableRow>
150-
))}
151-
</TableBody>
152-
</Table>
153-
</div>
121+
</TableHeader>
122+
<TableBody>
123+
{projects.map((project) => (
124+
<TableRow
125+
key={project.id}
126+
className="border-ox-gray border-y cursor-pointer"
127+
onClick={() => {
128+
handleClick(project.url);
129+
}}
130+
>
131+
<TableCell className="flex items-center gap-1 p-1 sm:p-2">
132+
<div className="rounded-full overflow-hidden inline-block h-4 w-4 sm:h-6 sm:w-6 border">
133+
<Image
134+
src={project.avatarUrl}
135+
className="w-full h-full object-cover"
136+
alt={project.name}
137+
width={10}
138+
height={10}
139+
/>
140+
</div>
141+
<TableCell className="text-white text-[10px] sm:text-xs text-ox-white font-semibold">
142+
{project.name}
143+
</TableCell>
144+
</TableCell>
145+
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white p-1 sm:p-2">
146+
{project.totalIssueCount}
147+
</TableCell>
148+
<TableCell className="text-center p-1 sm:p-2">
149+
<Badge
150+
variant="secondary"
151+
className={`${getColor(project.primaryLanguage)} text-[10px] sm:text-xs`}
152+
>
153+
{project.primaryLanguage}
154+
</Badge>
155+
</TableCell>
156+
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold p-1 sm:p-2">
157+
{project.popularity}
158+
</TableCell>
159+
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
160+
{project.stage}
161+
</TableCell>
162+
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
163+
{project.competition}
164+
</TableCell>
165+
<TableCell className="text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2">
166+
{project.activity}
167+
</TableCell>
168+
</TableRow>
169+
))}
170+
</TableBody>
171+
</Table>
172+
</div>
173+
) : isProjectsPage ? (
174+
<div className="flex flex-col justify-center items-center h-[calc(100vh-200px)] text-zinc-400 space-y-6">
175+
<div className="flex flex-col items-center gap-2">
176+
<MagnifyingGlassIcon className="size-12 text-ox-purple animate-pulse" />
177+
<p className="text-xl font-medium">Find Your Next Project</p>
178+
</div>
179+
<p className="text-base text-center max-w-md">
180+
Click the &apos;Find projects&apos; button above to discover open
181+
source projects that match your interests
182+
</p>
183+
</div>
184+
) : null}
154185
</div>
155186
);
156187
}

0 commit comments

Comments
 (0)