diff --git a/.vscode/settings.json b/.vscode/settings.json
index 05073cf..db28be9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,10 @@
{
"tailwindCSS.experimental.configFile": "packages/ui/src/styles/globals.css",
"editor.formatOnSave": true,
- "editor.defaultFormatter": "esbenp.prettier-vscode"
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "workbench.colorCustomizations": {
+ "editorInfo.foreground": "#0080ff6a",
+ "minimap.background": "#00000000",
+ "scrollbar.shadow": "#00000000"
+ }
}
diff --git a/apps/admin/app/(main)/page.tsx b/apps/admin/app/(main)/page.tsx
index db6e84f..fd17887 100644
--- a/apps/admin/app/(main)/page.tsx
+++ b/apps/admin/app/(main)/page.tsx
@@ -7,9 +7,11 @@ import { Button } from '@workspace/ui/components/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription } from '@workspace/ui/components/dialog';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@workspace/ui/components/accordion';
import { Badge } from '@workspace/ui/components/badge';
+import { Separator } from '@workspace/ui/components/separator';
import Link from 'next/link';
import { revalidatePath } from 'next/cache';
import { db, companies, jobs } from '@workspace/db';
+import { Plus, Building2, Briefcase, MapPin, DollarSign, Calendar, ExternalLink } from 'lucide-react';
async function createCompany(formData: FormData) {
'use server';
@@ -58,62 +60,281 @@ async function createJob(formData: FormData) {
}
async function getDashboardData() {
- return await db.query.companies.findMany({ with: { jobs: true } });
+ try {
+ // First, let's test a simple query without relations
+ const companiesOnly = await db.select().from(companies);
+ console.log('Companies query successful:', companiesOnly.length);
+
+ // Now try the relation query
+ const result = await db.query.companies.findMany({ with: { jobs: true } });
+ console.log('Full query successful:', result.length);
+ return result;
+ } catch (error) {
+ console.error('Database query error:', error);
+ // Fallback to companies only if the relation query fails
+ const companiesOnly = await db.select().from(companies);
+ return companiesOnly.map(company => ({ ...company, jobs: [] }));
+ }
}
export default async function DashboardPage() {
const data = await getDashboardData();
return (
-
-
- Companies Dashboard
-
-
-
-
- {data.map((company) => (
-
-
{company.name}
-
- {company.jobs.length > 0 ? (
- company.jobs.map((job) => (
-
-
- {job.title}
- {job.location}
- {job.salary}
- {job.active ? 'Active' : 'Inactive'}
-
-
- ))
- ) : (
-
- No jobs
-
- )}
+
+
+ {/* Header Section */}
+
+
+ {/* Stats Cards */}
+
+
+
+
+
+
Total Companies
+
{data.length}
+
+
+
+
+
+
+
+
+
+
Total Jobs
+
{data.reduce((acc, company) => acc + company.jobs.length, 0)}
+
+
+
+
+
+
+
+
+
+
Active Jobs
+
{data.reduce((acc, company) => acc + company.jobs.filter(job => job.active).length, 0)}
+
+
+
+
+
+
+
+
+ {/* Companies Section */}
+
+ {data.length === 0 ? (
+
+
+
+ No companies yet
+ Get started by adding your first company
+
+
+
+ ) : (
+ data.map((company) => (
+
+
+
+
+
+
+
+
+
{company.name}
+
{company.email}
+
+
+
+
+ {company.jobs.length} job{company.jobs.length !== 1 ? 's' : ''}
+
+
+
+ {company.description && company.description !== 'N/A' && (
+ {company.description}
+ )}
+
+
+
+
+
+
+
Job Listings
+
+ Add Job
+
+
+
+
+ {company.jobs.length > 0 ? (
+ company.jobs.map((job) => (
+
+
+
+
+
{job.title}
+
+ {job.active ? 'Active' : 'Inactive'}
+
+
+
+
+ {job.location && job.location !== 'N/A' && (
+
+
+ {job.location}
+
+ )}
+
+ {job.salary && job.salary !== 'N/A' && (
+
+
+ {job.salary}
+
+ )}
+
+
+
+ Deadline: {job.applicationDeadline.toLocaleDateString()}
+
+
+
+ {job.link && (
+
+ )}
+
+
+
+ ))
+ ) : (
+
+
+
+
No jobs yet
+
This company doesn't have any job listings
+
+
+
+
+
+ )}
+
+
+
+ ))
+ )}
+
+
);
}
diff --git a/packages/db/schema.ts b/packages/db/schema.ts
index 3ef9a90..914b00b 100644
--- a/packages/db/schema.ts
+++ b/packages/db/schema.ts
@@ -238,7 +238,7 @@ export const applications = pgTable('applications', {
.notNull(),
});
-export const comapnyRelations = relations(companies, ({ many }) => ({
+export const companyRelations = relations(companies, ({ many }) => ({
jobs: many(jobs),
}));
diff --git a/packages/ui/src/components/avatar.tsx b/packages/ui/src/components/avatar.tsx
new file mode 100644
index 0000000..55950ae
--- /dev/null
+++ b/packages/ui/src/components/avatar.tsx
@@ -0,0 +1,47 @@
+import * as React from "react"
+import * as AvatarPrimitive from "@radix-ui/react-avatar"
+import { cn } from "@workspace/ui/lib/utils"
+
+const Avatar = React.forwardRef<
+ React.ElementRef
,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+Avatar.displayName = "Avatar"
+
+const AvatarImage = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+AvatarImage.displayName = "AvatarImage"
+
+const AvatarFallback = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+AvatarFallback.displayName = "AvatarFallback"
+
+export { Avatar, AvatarImage, AvatarFallback }
\ No newline at end of file