diff --git a/app/api/controllers/route.ts b/app/api/controllers/route.ts index 5eaed9c..d1486a7 100644 --- a/app/api/controllers/route.ts +++ b/app/api/controllers/route.ts @@ -11,7 +11,7 @@ export async function GET() { }, distinct: ['cid'], }) - console.log(controllers) + // console.log(controllers) return NextResponse.json(controllers) } catch (error) { console.error('Failed to fetch controller data:', error) diff --git a/app/api/cron/update-controllers/route.ts b/app/api/cron/update-controllers/route.ts index 480b49c..82c1f03 100644 --- a/app/api/cron/update-controllers/route.ts +++ b/app/api/cron/update-controllers/route.ts @@ -11,6 +11,22 @@ const facilityTypes = { 6: "CTR", } as const; +const ratings = { + "-1": "INA", + "0": "SUS", + "1": "OBS", + "2": "S1", + "3": "S2", + "4": "S3", + "5": "C1", + "6": "C2", + "7": "C3", + "8": "I1", + "9": "I2", + "10": "I3", + "11": "SUP", + "12": "ADM", +} const CZQM_AIRPORTS = ["CYHZ", "CYFC", "CYQM", "CYSJ", "CYZX", "CYYG", "CYYT", "CYQX", "CYYR", "LFVP", "CYQI", "CYAY", "CYDF", "CYJT"]; export const dynamic = 'force-dynamic' export async function GET() { @@ -22,7 +38,7 @@ export async function GET() { // Filter controllers in CZQM airspace const czqmControllers = data.controllers.filter((controller: any) => { const callsign = controller.callsign; - return callsign.startsWith('CZQM_') || + return callsign.startsWith('CZQM_') || callsign.startsWith('CZQX_') || CZQM_AIRPORTS.some(airport => callsign.startsWith(airport)); }); @@ -41,6 +57,7 @@ export async function GET() { callsign: controller.callsign, facilityType: facilityType, frequency: controller.frequency, + rating: ratings[controller.rating], airport: airport, lastSeen: new Date(), logonTime: new Date(controller.logon_time), diff --git a/components/controller-profile.tsx b/components/controller-profile.tsx index 1817ea7..813112a 100644 --- a/components/controller-profile.tsx +++ b/components/controller-profile.tsx @@ -9,8 +9,23 @@ import { import { Skeleton } from "@/components/ui/skeleton"; import { Card } from "@/components/ui/card"; import { formatDistanceToNow, format } from "date-fns"; -import { Clock, Calendar, Radio } from "lucide-react"; - +import { Clock, Calendar, Radio, Star } from "lucide-react"; +const ratings = { + "-1": "INA", + "0": "SUS", + "1": "OBS", + "2": "S1", + "3": "S2", + "4": "S3", + "5": "C1", + "6": "C2", + "7": "C3", + "8": "I1", + "9": "I2", + "10": "I3", + "11": "SUP", + "12": "ADM", +} interface ControllerProfileProps { sessions: any[]; loading: boolean; @@ -34,41 +49,48 @@ export function ControllerProfile({ sessions, loading }: ControllerProfileProps) return (
-
- -
- -

Total Time

-
-

- {totalHours}h {totalMinutes}m -

-
- - -
- -

Total Sessions

-
-

{sessions.length}

-
- - -
- -

Positions

-
-
- {positions.map(position => ( - - {position} - - ))} -
-
+
+ {[ + { + icon: , + title: "Total Time", + value: `${totalHours}h ${totalMinutes}m`, + }, + { + icon: , + title: "Total Sessions", + value: sessions.length, + }, + { + icon: , + title: "Positions", + value: ( +
+ {positions.map(position => ( + + {position} + + ))} +
+ ), + }, + { + icon:
@@ -82,6 +104,7 @@ export function ControllerProfile({ sessions, loading }: ControllerProfileProps) Airport Frequency Duration + Rating @@ -97,6 +120,7 @@ export function ControllerProfile({ sessions, loading }: ControllerProfileProps) {formatSessionDuration(session.logonTime, session.lastSeen)} + {session.rating} ))} @@ -116,7 +140,8 @@ function formatSessionDuration(start: string, end: string) { function LoadingSkeleton() { return (
-
+
+ @@ -136,4 +161,4 @@ function LoadingSkeleton() {
); -} \ No newline at end of file +} diff --git a/components/controller-table.tsx b/components/controller-table.tsx index b9c1a53..026b58d 100644 --- a/components/controller-table.tsx +++ b/components/controller-table.tsx @@ -36,6 +36,7 @@ export function ControllerTable({ data, loading }: ControllerTableProps) { Current Position Airport Frequency + Rating Last Seen Session Duration @@ -52,6 +53,7 @@ export function ControllerTable({ data, loading }: ControllerTableProps) { {controller.callsign} {controller.airport} {controller.frequency} + {controller.rating} {formatDistanceToNow(new Date(controller.lastSeen), { addSuffix: true })} @@ -82,6 +84,7 @@ function LoadingSkeleton() { +
diff --git a/prisma/migrations/20241129063208_/migration.sql b/prisma/migrations/20241129063208_/migration.sql new file mode 100644 index 0000000..be09346 --- /dev/null +++ b/prisma/migrations/20241129063208_/migration.sql @@ -0,0 +1,22 @@ +-- CreateTable +CREATE TABLE "controller_sessions" ( + "id" SERIAL NOT NULL, + "cid" TEXT NOT NULL, + "name" TEXT NOT NULL, + "callsign" TEXT NOT NULL, + "facilityType" TEXT NOT NULL, + "frequency" TEXT NOT NULL, + "airport" TEXT NOT NULL, + "rating" TEXT NOT NULL, + "last_seen" TIMESTAMP(3) NOT NULL, + "logon_time" TIMESTAMP(3) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "controller_sessions_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "controller_sessions_cid_idx" ON "controller_sessions"("cid"); + +-- CreateIndex +CREATE INDEX "controller_sessions_last_seen_idx" ON "controller_sessions"("last_seen"); diff --git a/prisma/migrations/20241129063418_migrate/migration.sql b/prisma/migrations/20241129063418_migrate/migration.sql new file mode 100644 index 0000000..686c3ea --- /dev/null +++ b/prisma/migrations/20241129063418_migrate/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "controller_sessions" ALTER COLUMN "rating" DROP NOT NULL; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2db671a..46837a6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -15,6 +15,7 @@ model ControllerSession { facilityType String frequency String airport String + rating String? lastSeen DateTime @map("last_seen") logonTime DateTime @map("logon_time") createdAt DateTime @default(now()) @map("created_at")