From 63b0721859c21aafa2ff43f676c5dd1b5db98b60 Mon Sep 17 00:00:00 2001 From: vergiLgood1 Date: Fri, 25 Apr 2025 02:04:04 +0700 Subject: [PATCH] feat: add initial data seeding for resources, roles, demographics, crime incidents, and geographic data - Created resources data structure in `resources.ts` - Added roles data structure in `roles.ts` - Implemented seeding for crime categories and incidents with detailed logic in `crime-category.ts` and `crime-incident.ts` - Developed demographic data seeding logic in `demographic.ts` - Implemented geographic data seeding from GeoJSON files in `geographic.ts` - Added permission seeding logic in `permission.ts` - Created resource and role seeding scripts in `resource.ts` and `role.ts` --- .../(admin)/_components/app-sidebar.tsx | 2 +- .../settings/preference-settings.tsx | 4 +- .../_components/analytics-header.tsx | 26 + .../_components/case-resolution-rates.tsx | 79 + .../_components/crime-trends.tsx | 198 ++ .../_components/custom-report-builder.tsx | 92 + .../_components/geographical-analysis.tsx | 98 + .../_components/incident-type-breakdown.tsx | 145 ++ .../officer-performance-metrics.tsx | 85 + .../_components/predictive-analytics.tsx | 84 + .../_components/response-time-metrics.tsx | 103 + .../_components/time-of-day-analysis.tsx | 80 + .../analytics-reporting/action.ts} | 0 .../analytics-reporting/page.tsx | 101 + .../_components/community-events.tsx | 68 + .../_components/community-feedback.tsx | 50 + .../_components/community-header.tsx | 27 + .../_components/community-map.tsx | 72 + .../_components/crime-alerts.tsx | 117 + .../_components/crime-statistics.tsx | 155 ++ .../_components/faq-section.tsx | 54 + .../_components/neighborhood-watch.tsx | 62 + .../_components/report-incident.tsx | 62 + .../_components/resource-directory.tsx | 58 + .../_components/safety-tips.tsx | 46 + .../community-engagement/action.ts | 0 .../community-engagement/page.tsx | 110 + .../_components/case-assignees.tsx | 69 + .../_components/case-documents.tsx | 92 + .../_components/case-evidence.tsx | 93 + .../_components/case-header.tsx | 47 + .../crime-incident/_components/case-notes.tsx | 72 + .../_components/case-related.tsx | 59 + .../_components/case-timeline.tsx | 78 + .../_components/case-witnesses.tsx | 87 + .../crime-management/crime-incident/action.ts | 0 .../crime-management/crime-incident/page.tsx | 101 + .../evidence/_components/chain-of-custody.tsx | 84 + .../evidence/_components/digital-evidence.tsx | 66 + .../evidence/_components/evidence-by-case.tsx | 74 + .../evidence/_components/evidence-catalog.tsx | 129 + .../_components/evidence-disposal.tsx | 74 + .../evidence/_components/evidence-header.tsx | 24 + .../evidence/_components/evidence-search.tsx | 57 + .../evidence/_components/lab-analysis.tsx | 98 + .../_components/storage-locations.tsx | 82 + .../crime-management/evidence/action.ts | 0 .../crime-management/evidence/page.tsx | 92 + .../officer/_components/department-header.tsx | 24 + .../_components/equipment-assignments.tsx | 65 + .../officer/_components/incident-reports.tsx | 92 + .../officer/_components/leave-management.tsx | 62 + .../_components/officer-performance.tsx | 55 + .../officer/_components/officer-roster.tsx | 132 + .../officer/_components/shift-schedule.tsx | 85 + .../officer/_components/specialized-units.tsx | 67 + .../officer/_components/training-status.tsx | 61 + .../crime-management/officer/action.tsx | 0 .../crime-management/officer/page.tsx | 92 + .../_components/active-incidents.tsx | 143 ++ .../_components/dispatch-communications.tsx | 87 + .../_components/dispatch-header.tsx | 29 + .../_components/dispatch-map.tsx | 110 + .../_components/incident-history.tsx | 73 + .../_components/priority-queue.tsx | 86 + .../_components/resource-availability.tsx | 75 + .../_components/response-times.tsx | 97 + .../_components/shift-schedule.tsx | 80 + .../_components/unit-status.tsx | 65 + .../resource-dispatch/actions.ts | 0 .../resource-dispatch/page.tsx | 101 + sigap-website/app/(pages)/(auth)/action.ts | 151 +- sigap-website/app/_components/ui/chart.tsx | 364 +++ sigap-website/app/_styles/globals.css | 18 +- sigap-website/app/_utils/common.ts | 190 +- .../app/_utils/supabase/middleware.ts | 23 +- sigap-website/package-lock.json | 20 + sigap-website/package.json | 2 + sigap-website/prisma/data/crime-category.ts | 270 -- .../excels/administrations/demographics.xlsx | Bin 0 -> 12697 bytes .../excels/administrations/geographics.xlsx | Bin 0 -> 11760 bytes .../excels/administrations/polsek_jember.csv | 33 + .../excels/administrations/polsek_jember.xlsx | Bin 0 -> 12844 bytes .../excels/administrations/units_2020.csv | 34 + .../data/excels/crimes/crime_monthly.csv | 1861 ++++++++++++++ .../data/excels/crimes/crime_yearly.csv | 156 ++ .../data/excels/others/crime_categories.xlsx | Bin 0 -> 14997 bytes .../prisma/data/jsons/crime-category.ts | 311 +++ .../prisma/data/jsons/crimes/crime 2020.json | 1892 +++++++++++++++ .../prisma/data/jsons/crimes/crime 2021.json | 1922 +++++++++++++++ .../prisma/data/jsons/crimes/crime 2022.json | 2042 ++++++++++++++++ .../prisma/data/jsons/crimes/crime 2023.json | 2162 +++++++++++++++++ .../prisma/data/jsons/crimes/crime 2024.json | 2042 ++++++++++++++++ .../data/jsons/crimes/crime summary.json | 32 + .../prisma/data/{ => jsons}/districts.ts | 0 .../prisma/data/{ => jsons}/languages.ts | 0 sigap-website/prisma/data/{ => jsons}/nav.ts | 0 .../prisma/data/{ => jsons}/resources.ts | 0 .../prisma/data/{ => jsons}/roles.ts | 0 .../prisma/data/jsons/summary/summary.json | 0 .../prisma/data/{ => jsons}/timezones.ts | 0 .../jsons/units/summary without polres.json | 22 + .../prisma/data/jsons/units/units 2020.json | 992 ++++++++ .../prisma/data/jsons/units/units 2021.json | 992 ++++++++ .../prisma/data/jsons/units/units 2022.json | 992 ++++++++ .../prisma/data/jsons/units/units 2023.json | 992 ++++++++ .../prisma/data/jsons/units/units 2024.json | 992 ++++++++ .../data/jsons/units/units summary.json | 32 + sigap-website/prisma/data/jsons/users.ts | 0 .../migration.sql | 546 +++++ .../migration.sql | 2 + .../prisma/migrations/migration_lock.toml | 3 + sigap-website/prisma/schema.prisma | 455 ++-- sigap-website/prisma/seed.ts | 20 +- sigap-website/prisma/seeds/crime-category.ts | 89 +- sigap-website/prisma/seeds/crime-incident.ts | 1786 ++++++++++---- sigap-website/prisma/seeds/crime-incidents.ts | 372 +++ sigap-website/prisma/seeds/crimes.ts | 428 ++++ sigap-website/prisma/seeds/demographic.ts | 177 +- sigap-website/prisma/seeds/geographic.ts | 242 +- sigap-website/prisma/seeds/permission.ts | 92 +- sigap-website/prisma/seeds/resource.ts | 32 +- sigap-website/prisma/seeds/role.ts | 37 +- sigap-website/prisma/seeds/units.ts | 302 +++ .../prisma/utils/crime-score-calculator.ts | 282 +++ .../auth/sign-in-with-password.use-case.ts | 20 +- .../supabase}/.gitignore | 0 .../supabase}/config.toml | 53 +- .../20250421113117_remote_schema.sql | 1559 ++++++++++++ .../20250421114454_add_prisma_user.sql | 159 ++ .../20250421115005_remote_schema.sql | 327 +++ ...50421115206_grant_privileges_to_prisma.sql | 160 ++ ...0250424033411_grant_deafult_previleges.sql | 11 + ...4180834_grant_deafult_previleges_again.sql | 11 + .../20250227085404_remote_schema.sql | 212 -- .../20250227091031_remote_schema.sql | 189 -- ...20250227091713_user_management_starter.sql | 55 - 137 files changed, 29515 insertions(+), 1782 deletions(-) create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/analytics-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/case-resolution-rates.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/crime-trends.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/custom-report-builder.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/geographical-analysis.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/incident-type-breakdown.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/officer-performance-metrics.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/predictive-analytics.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/response-time-metrics.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/time-of-day-analysis.tsx rename sigap-website/{prisma/data/users.tsx => app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/action.ts} (100%) create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/page.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-events.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-feedback.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-map.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-alerts.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-statistics.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/faq-section.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/neighborhood-watch.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/report-incident.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/resource-directory.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/safety-tips.tsx rename supabase/migrations/20250227092633_user_management_starter.sql => sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/action.ts (100%) create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/page.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-assignees.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-documents.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-evidence.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-notes.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-related.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-timeline.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-witnesses.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/action.ts create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/page.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/chain-of-custody.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/digital-evidence.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/evidence-by-case.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/evidence-catalog.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/evidence-disposal.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/evidence-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/evidence-search.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/lab-analysis.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/_components/storage-locations.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/action.ts create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/evidence/page.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/department-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/equipment-assignments.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/incident-reports.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/leave-management.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/officer-performance.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/officer-roster.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/shift-schedule.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/specialized-units.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/_components/training-status.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/action.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/officer/page.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/active-incidents.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/dispatch-communications.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/dispatch-header.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/dispatch-map.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/incident-history.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/priority-queue.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/resource-availability.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/response-times.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/shift-schedule.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/_components/unit-status.tsx create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/actions.ts create mode 100644 sigap-website/app/(pages)/(admin)/dashboard/crime-management/resource-dispatch/page.tsx create mode 100644 sigap-website/app/_components/ui/chart.tsx delete mode 100644 sigap-website/prisma/data/crime-category.ts create mode 100644 sigap-website/prisma/data/excels/administrations/demographics.xlsx create mode 100644 sigap-website/prisma/data/excels/administrations/geographics.xlsx create mode 100644 sigap-website/prisma/data/excels/administrations/polsek_jember.csv create mode 100644 sigap-website/prisma/data/excels/administrations/polsek_jember.xlsx create mode 100644 sigap-website/prisma/data/excels/administrations/units_2020.csv create mode 100644 sigap-website/prisma/data/excels/crimes/crime_monthly.csv create mode 100644 sigap-website/prisma/data/excels/crimes/crime_yearly.csv create mode 100644 sigap-website/prisma/data/excels/others/crime_categories.xlsx create mode 100644 sigap-website/prisma/data/jsons/crime-category.ts create mode 100644 sigap-website/prisma/data/jsons/crimes/crime 2020.json create mode 100644 sigap-website/prisma/data/jsons/crimes/crime 2021.json create mode 100644 sigap-website/prisma/data/jsons/crimes/crime 2022.json create mode 100644 sigap-website/prisma/data/jsons/crimes/crime 2023.json create mode 100644 sigap-website/prisma/data/jsons/crimes/crime 2024.json create mode 100644 sigap-website/prisma/data/jsons/crimes/crime summary.json rename sigap-website/prisma/data/{ => jsons}/districts.ts (100%) rename sigap-website/prisma/data/{ => jsons}/languages.ts (100%) rename sigap-website/prisma/data/{ => jsons}/nav.ts (100%) rename sigap-website/prisma/data/{ => jsons}/resources.ts (100%) rename sigap-website/prisma/data/{ => jsons}/roles.ts (100%) create mode 100644 sigap-website/prisma/data/jsons/summary/summary.json rename sigap-website/prisma/data/{ => jsons}/timezones.ts (100%) create mode 100644 sigap-website/prisma/data/jsons/units/summary without polres.json create mode 100644 sigap-website/prisma/data/jsons/units/units 2020.json create mode 100644 sigap-website/prisma/data/jsons/units/units 2021.json create mode 100644 sigap-website/prisma/data/jsons/units/units 2022.json create mode 100644 sigap-website/prisma/data/jsons/units/units 2023.json create mode 100644 sigap-website/prisma/data/jsons/units/units 2024.json create mode 100644 sigap-website/prisma/data/jsons/units/units summary.json create mode 100644 sigap-website/prisma/data/jsons/users.ts create mode 100644 sigap-website/prisma/migrations/20250423141344_init_migration/migration.sql create mode 100644 sigap-website/prisma/migrations/20250423155055_add_phone_and_create_polres_jemebr/migration.sql create mode 100644 sigap-website/prisma/migrations/migration_lock.toml create mode 100644 sigap-website/prisma/seeds/crime-incidents.ts create mode 100644 sigap-website/prisma/seeds/crimes.ts create mode 100644 sigap-website/prisma/seeds/units.ts create mode 100644 sigap-website/prisma/utils/crime-score-calculator.ts rename {supabase => sigap-website/supabase}/.gitignore (100%) rename {supabase => sigap-website/supabase}/config.toml (88%) create mode 100644 sigap-website/supabase/migrations/20250421113117_remote_schema.sql create mode 100644 sigap-website/supabase/migrations/20250421114454_add_prisma_user.sql create mode 100644 sigap-website/supabase/migrations/20250421115005_remote_schema.sql create mode 100644 sigap-website/supabase/migrations/20250421115206_grant_privileges_to_prisma.sql create mode 100644 sigap-website/supabase/migrations/20250424033411_grant_deafult_previleges.sql create mode 100644 sigap-website/supabase/migrations/20250424180834_grant_deafult_previleges_again.sql delete mode 100644 supabase/migrations/20250227085404_remote_schema.sql delete mode 100644 supabase/migrations/20250227091031_remote_schema.sql delete mode 100644 supabase/migrations/20250227091713_user_management_starter.sql diff --git a/sigap-website/app/(pages)/(admin)/_components/app-sidebar.tsx b/sigap-website/app/(pages)/(admin)/_components/app-sidebar.tsx index 291f797..1ccc22e 100644 --- a/sigap-website/app/(pages)/(admin)/_components/app-sidebar.tsx +++ b/sigap-website/app/(pages)/(admin)/_components/app-sidebar.tsx @@ -14,7 +14,7 @@ import { SidebarRail, } from "@/app/_components/ui/sidebar"; import { NavPreMain } from "./navigations/nav-pre-main"; -import { navData } from "@/prisma/data/nav"; +import { navData } from "@/prisma/data/jsons/nav"; import { TeamSwitcher } from "../../../_components/team-switcher"; import { useGetCurrentUserQuery } from "../dashboard/user-management/_queries/queries"; diff --git a/sigap-website/app/(pages)/(admin)/_components/settings/preference-settings.tsx b/sigap-website/app/(pages)/(admin)/_components/settings/preference-settings.tsx index 843243e..b1746ed 100644 --- a/sigap-website/app/(pages)/(admin)/_components/settings/preference-settings.tsx +++ b/sigap-website/app/(pages)/(admin)/_components/settings/preference-settings.tsx @@ -23,8 +23,8 @@ import { applyCookiePreferences, } from "@/app/_utils/cookies/cookies-manager"; import { toast } from "sonner"; -import { initialTimezones, TimezoneType } from "@/prisma/data/timezones"; -import { languages, LanguageType } from "@/prisma/data/languages"; +import { initialTimezones, TimezoneType } from "@/prisma/data/jsons/timezones"; +import { languages, LanguageType } from "@/prisma/data/jsons/languages"; export default function PreferencesSettings() { const [language, setLanguage] = useState("en-US"); diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/analytics-header.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/analytics-header.tsx new file mode 100644 index 0000000..407f7ee --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/analytics-header.tsx @@ -0,0 +1,26 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Button } from "@/app/_components/ui/button" +import { Download, Calendar } from "lucide-react" + +export default function AnalyticsHeader() { + return ( +
+
+

Analytics & Reporting

+

Crime statistics, trends, and performance metrics

+
+
+
+ + + Apr 1 - Apr 30, 2023 + +
+ +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/case-resolution-rates.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/case-resolution-rates.tsx new file mode 100644 index 0000000..985e04d --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/case-resolution-rates.tsx @@ -0,0 +1,79 @@ +"use client" + +import { Progress } from "@/app/_components/ui/progress" +import { Badge } from "@/app/_components/ui/badge" +import { TrendingUp, TrendingDown } from "lucide-react" + +export default function CaseResolutionRates() { + const resolutionData = [ + { + type: "Homicide", + rate: 72, + trend: "+5%", + direction: "up", + }, + { + type: "Assault", + rate: 65, + trend: "+3%", + direction: "up", + }, + { + type: "Robbery", + rate: 48, + trend: "-2%", + direction: "down", + }, + { + type: "Theft", + rate: 35, + trend: "+1%", + direction: "up", + }, + { + type: "Cybercrime", + rate: 28, + trend: "-4%", + direction: "down", + }, + ] + + return ( +
+
+
+
52%
+
Overall Case Clearance
+
+ + +2% from last month + +
+ +
+ {resolutionData.map((item) => ( +
+
+ {item.type} +
+ {item.rate}% + + {item.direction === "up" ? ( + + ) : ( + + )} + +
+
+ 60 ? "bg-green-500" : item.rate > 40 ? "bg-yellow-500" : "bg-red-500"} + /> +
+ ))} +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/crime-trends.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/crime-trends.tsx new file mode 100644 index 0000000..f14689f --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/crime-trends.tsx @@ -0,0 +1,198 @@ +"use client" + +import { useState } from "react" +import { Button } from "@/app/_components/ui/button" +import { Tabs, TabsList, TabsTrigger } from "@/app/_components/ui/tabs" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + ChartLegend, + ChartConfig, + ChartLegendContent, +} from "@/app/_components/ui/chart" +import { Line, LineChart, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip, BarChart } from "recharts" + +const chartConfig = { + desktop: { + label: "Desktop", + color: "#2563eb", + }, + mobile: { + label: "Mobile", + color: "#60a5fa", + }, +} satisfies ChartConfig + +export default function CrimeTrends() { + const [timeRange, setTimeRange] = useState("6m") + const [chartType, setChartType] = useState("all") + + // Sample data for the chart + const data = [ + { month: "Jan", violent: 42, property: 85, cyber: 18, other: 30 }, + { month: "Feb", violent: 38, property: 78, cyber: 22, other: 28 }, + { month: "Mar", violent: 45, property: 82, cyber: 25, other: 32 }, + { month: "Apr", violent: 40, property: 75, cyber: 30, other: 35 }, + { month: "May", violent: 35, property: 72, cyber: 28, other: 30 }, + { month: "Jun", violent: 32, property: 68, cyber: 32, other: 28 }, + ] + + return ( +
+
+ + + All Crimes + Violent + Property + Cyber + + + +
+ + + + +
+
+ + + <> + + + + + + } /> + {chartType === "all" || chartType === "violent" ? ( + + ) : null} + {chartType === "all" || chartType === "property" ? ( + + ) : null} + {chartType === "all" || chartType === "cyber" ? ( + + ) : null} + {chartType === "all" ? ( + + ) : null} + + + + {chartType === "all" || chartType === "violent" ? ( + +
+
+ Violent Crime +
+
+ ) : null} + {chartType === "all" || chartType === "property" ? ( + +
+
+ Property Crime +
+
+ ) : null} + {chartType === "all" || chartType === "cyber" ? ( + +
+
+ Cybercrime +
+
+ ) : null} + {chartType === "all" ? ( + +
+
+ Other +
+
+ ) : null} +
+ +
+
+ ) +} + +function CustomTooltip({ active, payload, label }: any) { + if (active && payload && payload.length) { + return ( + +
{label}
+ {payload.map((entry: any, index: number) => ( +
+
+ {entry.name}: + {entry.value} incidents +
+ ))} + + } /> + ) + } + + return null +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/custom-report-builder.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/custom-report-builder.tsx new file mode 100644 index 0000000..1fe8f62 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/custom-report-builder.tsx @@ -0,0 +1,92 @@ +import { Button } from "@/app/_components/ui/button" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/app/_components/ui/select" +import { Checkbox } from "@/app/_components/ui/checkbox" +import { Download, FileText } from "lucide-react" + +export default function CustomReportBuilder() { + const reportTypes = [ + { id: "crime-stats", label: "Crime Statistics" }, + { id: "officer-perf", label: "Officer Performance" }, + { id: "response-time", label: "Response Times" }, + { id: "case-resolution", label: "Case Resolution" }, + { id: "geographic", label: "Geographic Analysis" }, + ] + + const savedReports = [ + { name: "Monthly Crime Summary", date: "Apr 30, 2023", type: "PDF" }, + { name: "Q1 Performance Review", date: "Mar 31, 2023", type: "XLSX" }, + ] + + return ( +
+
+
+ + +
+ +
+ + +
+ +
+ +
+ {reportTypes.map((type) => ( +
+ + +
+ ))} +
+
+ + +
+ +
+

Saved Reports

+
+ {savedReports.map((report, index) => ( +
+
+
{report.name}
+
{report.date}
+
+ +
+ ))} +
+
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/geographical-analysis.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/geographical-analysis.tsx new file mode 100644 index 0000000..98958a7 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/geographical-analysis.tsx @@ -0,0 +1,98 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/app/_components/ui/select" + +export default function GeographicalAnalysis() { + return ( +
+
+ + + +
+ +
+
+ +
+
+ High Density +
+
+ Medium Density +
+
+ Low Density +
+
+ +
+ Crime Hotspot Map +
Showing data for April 2023
+
+
+ +
+
+

Highest Crime Areas

+
+
+ Downtown District + + High + +
+
+ West Side Commercial + + Medium + +
+
+ North Transit Hub + + Medium + +
+
+
+ +
+

Crime Reduction

+
+
+ East Residential + -15% MoM +
+
+ South Park Area + -8% MoM +
+
+ Central Business + +5% MoM +
+
+
+
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/incident-type-breakdown.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/incident-type-breakdown.tsx new file mode 100644 index 0000000..e0187a2 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/incident-type-breakdown.tsx @@ -0,0 +1,145 @@ +"use client" + +import { Tabs, TabsList, TabsTrigger } from "@/app/_components/ui/tabs" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + ChartLegend, + ChartLegendContent, + ChartConfig, +} from "@/app/_components/ui/chart" +import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from "recharts" +import { BarChart } from "lucide-react" + +const chartConfig = { + desktop: { + label: "Desktop", + color: "#2563eb", + }, + mobile: { + label: "Mobile", + color: "#60a5fa", + }, +} satisfies ChartConfig + +export default function IncidentTypeBreakdown() { + // Sample data for the chart + const data = [ + { name: "Theft", value: 35, color: "#3b82f6" }, + { name: "Assault", value: 20, color: "#ef4444" }, + { name: "Vandalism", value: 15, color: "#f59e0b" }, + { name: "Fraud", value: 10, color: "#10b981" }, + { name: "Drugs", value: 8, color: "#8b5cf6" }, + { name: "Other", value: 12, color: "#6b7280" }, + ] + + return ( +
+
+ + + Pie Chart + Bar Chart + + + + + + All Time + This Month + This Week + + +
+ +
+ + <> + + + + + {data.map((entry, index) => ( + + ))} + + } /> + + + + + {data.map((item) => ( + +
+ + {item.name} +
+
+ ))} +
+ +
+ +
+
+

Key Insights

+
    +
  • + + + Theft accounts for the largest portion of incidents (35%), with a 5% increase from the previous month. + +
  • +
  • + + Assault incidents have decreased by 3% compared to the previous month. +
  • +
  • + + Fraud reports have increased by 8%, indicating a growing trend in financial crimes. +
  • +
+
+ +
+

Recommendations

+
    +
  • + + Increase patrols in high-theft areas, particularly in commercial districts. +
  • +
  • + + Launch a public awareness campaign about fraud prevention. +
  • +
  • + + Continue community engagement programs that have helped reduce assault incidents. +
  • +
+
+
+
+
+ ) +} + +function CustomTooltip({ active, payload }: any) { + if (active && payload && payload.length) { + return ( + +
{payload[0].name}
+
+ {payload[0].value}% of total incidents +
+ + }> + +
+ ) + } + + return null +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/officer-performance-metrics.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/officer-performance-metrics.tsx new file mode 100644 index 0000000..aab3189 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/officer-performance-metrics.tsx @@ -0,0 +1,85 @@ +"use client" + +import { Progress } from "@/app/_components/ui/progress" +import { Award } from "lucide-react" + +export default function OfficerPerformanceMetrics() { + const officers = [ + { + name: "Emily Parker", + metric: "Case Clearance", + value: 92, + rank: 1, + }, + { + name: "Michael Chen", + metric: "Response Time", + value: 88, + rank: 2, + }, + { + name: "Sarah Johnson", + metric: "Evidence Processing", + value: 95, + rank: 3, + }, + ] + + const departmentMetrics = [ + { + name: "Cases Assigned", + value: 245, + change: "+12", + period: "this month", + }, + { + name: "Cases Closed", + value: 182, + change: "+8", + period: "this month", + }, + { + name: "Avg. Case Duration", + value: "18.5 days", + change: "-2.3", + period: "from last month", + }, + ] + + return ( +
+
+

+ + Top Performers +

+ +
+ {officers.map((officer) => ( +
+
+ {officer.name} + + {officer.metric}: {officer.value}% + +
+ +
+ ))} +
+
+ +
+ {departmentMetrics.map((metric) => ( +
+
{metric.name}
+
{metric.value}
+
+ {metric.change} {metric.period} +
+
+ ))} +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/predictive-analytics.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/predictive-analytics.tsx new file mode 100644 index 0000000..c90a2fd --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/predictive-analytics.tsx @@ -0,0 +1,84 @@ +import { Badge } from "@/app/_components/ui/badge" +import { AlertTriangle, TrendingUp } from "lucide-react" + +export default function PredictiveAnalytics() { + const predictions = [ + { + area: "Downtown District", + crimeType: "Theft", + riskLevel: "High", + confidence: "85%", + trend: "Increasing", + }, + { + area: "West Side Commercial", + crimeType: "Vandalism", + riskLevel: "Medium", + confidence: "72%", + trend: "Stable", + }, + { + area: "North Transit Hub", + crimeType: "Assault", + riskLevel: "Medium", + confidence: "68%", + trend: "Increasing", + }, + ] + + return ( +
+
+

7-Day Forecast

+ + AI-Powered + +
+ + {predictions.map((prediction, index) => ( +
+
+ +

{prediction.area}

+ + {prediction.riskLevel} Risk + +
+ +
+
+ Predicted Crime: + {prediction.crimeType} +
+
+ Confidence: + {prediction.confidence} +
+
+ Trend: + + {prediction.trend} + {prediction.trend === "Increasing" && } + +
+
+
+ ))} + +
+ Predictions based on historical data, weather patterns, and local events +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/response-time-metrics.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/response-time-metrics.tsx new file mode 100644 index 0000000..b721601 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/response-time-metrics.tsx @@ -0,0 +1,103 @@ +"use client" + +import { Progress } from "@/app/_components/ui/progress" +import { Clock, TrendingDown } from "lucide-react" +import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/app/_components/ui/chart" +import { Bar, BarChart, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip } from "recharts" + +export default function ResponseTimeMetrics() { + // Sample data for the chart + const data = [ + { name: "Violent", time: 4.2 }, + { name: "Theft", time: 8.5 }, + { name: "Domestic", time: 5.1 }, + { name: "Traffic", time: 9.8 }, + { name: "Noise", time: 12.3 }, + ] + + return ( +
+
+
+
4.2m
+
Average Response Time
+
+
+ + -0.3m from last month +
+
+ +
+
+
+ Priority 1 (Emergency) +
+ + 3.2 min avg +
+
+ +
+
+
+ Priority 2 (Urgent) +
+ + 5.8 min avg +
+
+ +
+
+
+ Priority 3 (Standard) +
+ + 12.5 min avg +
+
+ +
+
+ +
+ + + + + + + + } /> + + + + + +
+ +
Response time by incident type (minutes)
+
+ ) +} + +function CustomTooltip({ active, payload, label }: any) { + if (active && payload && payload.length) { + return ( + +
{label} Incidents
+
+ Avg. Response Time: + {payload[0].value} minutes +
+ + }> + +
+ ) + } + + return null +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/time-of-day-analysis.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/time-of-day-analysis.tsx new file mode 100644 index 0000000..fdd1d25 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/_components/time-of-day-analysis.tsx @@ -0,0 +1,80 @@ +"use client" + +import { Badge } from "@/app/_components/ui/badge" +import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/app/_components/ui/chart" +import { BarChart, Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from "recharts" + +export default function TimeOfDayAnalysis() { + // Sample data for the chart + const data = [ + { name: "Morning (6AM-12PM)", value: 15, color: "#3b82f6" }, + { name: "Afternoon (12PM-6PM)", value: 25, color: "#f59e0b" }, + { name: "Evening (6PM-12AM)", value: 40, color: "#8b5cf6" }, + { name: "Night (12AM-6AM)", value: 20, color: "#1e293b" }, + ] + + const highRiskTimes = [ + { day: "Friday", time: "10PM - 2AM", risk: "High" }, + { day: "Saturday", time: "11PM - 3AM", risk: "High" }, + { day: "Sunday", time: "12AM - 4AM", risk: "Medium" }, + ] + + return ( +
+ + + + + {data.map((entry, index) => ( + + ))} + + } /> + + + + +
+
Crime Distribution by Time of Day
+
Evening hours show highest incident rates
+
+ +
+

High-Risk Time Periods

+
+ {highRiskTimes.map((item, index) => ( +
+
+ {item.day}: {item.time} +
+ + {item.risk} Risk + +
+ ))} +
+
+
+ ) +} + +function CustomTooltip({ active, payload }: any) { + if (active && payload && payload.length) { + return ( + +
{payload[0].name}
+
+ {payload[0].value}% of incidents +
+ + }> +
+ ) + } + + return null +} diff --git a/sigap-website/prisma/data/users.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/action.ts similarity index 100% rename from sigap-website/prisma/data/users.tsx rename to sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/action.ts diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/page.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/page.tsx new file mode 100644 index 0000000..3312d8c --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/analytics-reporting/page.tsx @@ -0,0 +1,101 @@ +"use client" + +import { BentoGrid, BentoGridItem } from "@/app/_components/ui/bento-grid" +import { BarChart3, TrendingUp, Map, Calendar, Clock, FileText, AlertTriangle, Filter } from "lucide-react" +import AnalyticsHeader from "./_components/analytics-header" +import CrimeTrends from "./_components/crime-trends" +import GeographicalAnalysis from "./_components/geographical-analysis" +import ResponseTimeMetrics from "./_components/response-time-metrics" +import CaseResolutionRates from "./_components/case-resolution-rates" +import IncidentTypeBreakdown from "./_components/incident-type-breakdown" +import OfficerPerformanceMetrics from "./_components/officer-performance-metrics" +import TimeOfDayAnalysis from "./_components/time-of-day-analysis" +import CustomReportBuilder from "./_components/custom-report-builder" +import PredictiveAnalytics from "./_components/predictive-analytics" + +export default function AnalyticsReportingPage() { + return ( +
+
+ + + + } + colSpan="2" + > + + + + } + rowSpan="2" + > + + + + } + > + + + + } + > + + + + } + colSpan="2" + > + + + + } + > + + + + } + > + + + + } + > + + + + } + > + + + +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-events.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-events.tsx new file mode 100644 index 0000000..958e00f --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-events.tsx @@ -0,0 +1,68 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Calendar, MapPin } from "lucide-react" + +export default function CommunityEvents() { + const events = [ + { + title: "Community Safety Workshop", + date: "Apr 28, 2023", + time: "6:00 PM - 8:00 PM", + location: "Community Center", + type: "Workshop", + }, + { + title: "Coffee with a Cop", + date: "May 5, 2023", + time: "9:00 AM - 11:00 AM", + location: "Downtown Café", + type: "Meet & Greet", + }, + { + title: "Neighborhood Watch Meeting", + date: "May 12, 2023", + time: "7:00 PM - 8:30 PM", + location: "Public Library", + type: "Meeting", + }, + ] + + return ( +
+ {events.map((event, index) => ( +
+
+

{event.title}

+ + {event.type} + +
+ +
+
+ + {event.date}, {event.time} +
+
+ + {event.location} +
+
+ +
+
+ {[1, 2, 3].map((i) => ( +
+ ))} +
+ +8 +
+
+ +
+
+ ))} + + +
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-feedback.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-feedback.tsx new file mode 100644 index 0000000..804e39f --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-feedback.tsx @@ -0,0 +1,50 @@ +import { Button } from "@/app/_components/ui/button" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/app/_components/ui/select" +import { MessageSquare } from "lucide-react" + +export default function CommunityFeedback() { + return ( +
+
+ We value your input! Share your thoughts, concerns, or suggestions to help us better serve the community. +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-header.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-header.tsx new file mode 100644 index 0000000..ee9cf6b --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-header.tsx @@ -0,0 +1,27 @@ +import { Button } from "@/app/_components/ui/button" +import { Search, Phone } from "lucide-react" + +export default function CommunityHeader() { + return ( +
+
+

Community Engagement Portal

+

Stay informed, connected, and engaged with your local law enforcement

+
+
+
+ + +
+ +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-map.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-map.tsx new file mode 100644 index 0000000..cfe3bb1 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/community-map.tsx @@ -0,0 +1,72 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/app/_components/ui/select" + +export default function CommunityMap() { + return ( +
+
+ + +
+ + Last 7 Days + +
+
+ +
+
+ +
+
+ Theft +
+
+ Vandalism +
+
+ Traffic +
+
+ Resources +
+
+ +
+ Community Safety Map +
Showing incidents from Apr 17-24, 2023
+
+
+ +
+

Your Neighborhood

+
+
+ Downtown District + + Medium Risk + +
+
Recent incidents: 5 thefts, 2 vandalism reports
+
+ Trend: +12% from last month +
+
+ +
+
+
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-alerts.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-alerts.tsx new file mode 100644 index 0000000..d9f65c6 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-alerts.tsx @@ -0,0 +1,117 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Button } from "@/app/_components/ui/button" +import { AlertTriangle, MapPin, Clock, Bell } from "lucide-react" + +export default function CrimeAlerts() { + const alerts = [ + { + id: "ALT-1234", + type: "Theft", + description: + "Multiple vehicle break-ins reported in the Downtown area. Please secure valuables and lock vehicles.", + location: "Downtown District", + date: "Apr 23, 2023", + time: "Posted 2 hours ago", + severity: "Medium", + }, + { + id: "ALT-1235", + type: "Suspicious Activity", + description: + "Residents report unknown individuals going door-to-door claiming to represent utility companies. Always ask for proper identification.", + location: "North Residential Area", + date: "Apr 22, 2023", + time: "Posted 1 day ago", + severity: "Low", + }, + { + id: "ALT-1236", + type: "Scam Alert", + description: + "Phone scammers impersonating police officers requesting payment for 'outstanding warrants'. Police will never request payment over the phone.", + location: "Citywide", + date: "Apr 21, 2023", + time: "Posted 2 days ago", + severity: "High", + }, + ] + + return ( +
+
+
+ + +
+ +
+ +
+ {alerts.map((alert) => ( +
+
+ +
+ +
+
+

{alert.type}

+ + {alert.severity} Priority + +
+ +

{alert.description}

+ +
+
+ + {alert.location} +
+
+ + {alert.time} +
+
+
+ + +
+ ))} +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-statistics.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-statistics.tsx new file mode 100644 index 0000000..30fab8c --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/crime-statistics.tsx @@ -0,0 +1,155 @@ +"use client" + +import { Tabs, TabsList, TabsTrigger } from "@/app/_components/ui/tabs" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + ChartLegend, + ChartLegendContent, + ChartConfig, +} from "@/app/_components/ui/chart" +import { Bar, BarChart, Line, LineChart, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Tooltip } from "recharts" + +const chartConfig = { + desktop: { + label: "Desktop", + color: "#2563eb", + }, + mobile: { + label: "Mobile", + color: "#60a5fa", + }, +} satisfies ChartConfig + +export default function CrimeStatistics() { + // Sample data for the chart + const monthlyData = [ + { month: "Jan", violent: 12, property: 45, other: 20 }, + { month: "Feb", violent: 10, property: 42, other: 18 }, + { month: "Mar", violent: 15, property: 48, other: 22 }, + { month: "Apr", violent: 8, property: 40, other: 15 }, + { month: "May", violent: 12, property: 38, other: 20 }, + { month: "Jun", violent: 10, property: 35, other: 18 }, + ] + + const neighborhoodData = [ + { name: "Downtown", incidents: 45 }, + { name: "Westside", incidents: 32 }, + { name: "North", incidents: 28 }, + { name: "East", incidents: 22 }, + { name: "South", incidents: 18 }, + ] + + return ( +
+
+ + + Crime Trends + By Neighborhood + + + + + + 3 Months + 6 Months + 1 Year + + +
+ +
+ + <> + + + + + + } /> + + + + + + + +
+
+ Violent Crime +
+
+
+ Property Crime +
+
+
+ Other +
+
+ + +
+ + + + + + + + } /> + + + + +
+ +
+ Data source: City Police Department. Last updated: April 24, 2023 +
+
+ ) +} + +function CustomLineTooltip({ active, payload, label }: any) { + if (active && payload && payload.length) { + return ( + +
{label}
+ {payload.map((entry: any, index: number) => ( +
+
+ {entry.name}: + {entry.value} incidents +
+ ))} + + }> +
+ ) + } + + return null +} + +function CustomBarTooltip({ active, payload, label }: any) { + if (active && payload && payload.length) { + return ( + +
{label} Neighborhood
+
+ Total Incidents: + {payload[0].value} +
+ + }> +
+ ) + } + + return null +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/faq-section.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/faq-section.tsx new file mode 100644 index 0000000..7f68d7c --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/faq-section.tsx @@ -0,0 +1,54 @@ +"use client" + +import { useState } from "react" +import { ChevronDown } from "lucide-react" + +export default function FAQSection() { + const faqs = [ + { + question: "How do I report a non-emergency incident?", + answer: + "You can use the 'Report an Incident' form on this portal, call the non-emergency number at 555-123-4567, or visit your local police station in person.", + }, + { + question: "How can I join a Neighborhood Watch group?", + answer: + "Check the 'Neighborhood Watch' section for groups in your area. You can contact the coordinator directly or click 'Start or Join a Group' for more information.", + }, + { + question: "What should I do if I witness a crime?", + answer: + "If it's an emergency or crime in progress, call 911 immediately. For non-emergencies, use the non-emergency line or the reporting form on this portal.", + }, + { + question: "How can I request extra patrols in my neighborhood?", + answer: + "Contact your local precinct or submit a request through the 'Community Feedback' section of this portal.", + }, + ] + + const [openIndex, setOpenIndex] = useState(null) + + const toggleFAQ = (index: number) => { + setOpenIndex(openIndex === index ? null : index) + } + + return ( +
+ {faqs.map((faq, index) => ( +
+ + {openIndex === index &&
{faq.answer}
} +
+ ))} + + +
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/neighborhood-watch.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/neighborhood-watch.tsx new file mode 100644 index 0000000..1e3fe53 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/neighborhood-watch.tsx @@ -0,0 +1,62 @@ +import { Badge } from "@/app/_components/ui/badge" +import { Users, MapPin, Phone } from "lucide-react" + +export default function NeighborhoodWatch() { + const groups = [ + { + name: "Downtown Watch Group", + coordinator: "Sarah Johnson", + members: 24, + area: "Downtown District", + contact: "555-123-4567", + }, + { + name: "Westside Neighbors", + coordinator: "Michael Chen", + members: 18, + area: "West Residential Area", + contact: "555-234-5678", + }, + { + name: "Parkview Safety", + coordinator: "Emily Parker", + members: 15, + area: "Park District", + contact: "555-345-6789", + }, + ] + + return ( +
+ {groups.map((group, index) => ( +
+
+
+ +
+
+

{group.name}

+
Coordinator: {group.coordinator}
+
+ + {group.members} members + +
+ +
+
+ + {group.area} +
+
+ + {group.contact} +
+
+
+ ))} + + +
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/report-incident.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/report-incident.tsx new file mode 100644 index 0000000..8f63515 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/report-incident.tsx @@ -0,0 +1,62 @@ +import { Button } from "@/app/_components/ui/button" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/app/_components/ui/select" +import { FileText, MapPin, Camera } from "lucide-react" + +export default function ReportIncident() { + return ( +
+
+ Use this form to report non-emergency incidents. For emergencies, please call 911. +
+ +
+
+ + +
+ +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/resource-directory.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/resource-directory.tsx new file mode 100644 index 0000000..b46965c --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/resource-directory.tsx @@ -0,0 +1,58 @@ +import { Phone, Building, Heart, Shield } from "lucide-react" + +export default function ResourceDirectory() { + const resources = [ + { + name: "Police Non-Emergency", + category: "Law Enforcement", + contact: "555-123-4567", + icon: Shield, + }, + { + name: "Victim Services", + category: "Support", + contact: "555-234-5678", + icon: Heart, + }, + { + name: "City Hall", + category: "Government", + contact: "555-345-6789", + icon: Building, + }, + { + name: "Mental Health Hotline", + category: "Support", + contact: "555-456-7890", + icon: Heart, + }, + ] + + return ( +
+ {resources.map((resource, index) => ( +
+
+
+ +
+
+

{resource.name}

+
{resource.category}
+
+
+ +
+
+ + {resource.contact} +
+ +
+
+ ))} + + +
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/safety-tips.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/safety-tips.tsx new file mode 100644 index 0000000..25f464c --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/_components/safety-tips.tsx @@ -0,0 +1,46 @@ +import { Home, Car, Smartphone } from "lucide-react" + +export default function SafetyTips() { + const categories = [ + { + name: "Home Security", + icon: Home, + tips: ["Lock all doors and windows when away", "Install motion-sensor lighting", "Consider a security system"], + }, + { + name: "Vehicle Protection", + icon: Car, + tips: ["Always lock your vehicle", "Don't leave valuables visible", "Park in well-lit areas"], + }, + { + name: "Digital Safety", + icon: Smartphone, + tips: ["Use strong, unique passwords", "Be cautious of suspicious emails", "Keep software updated"], + }, + ] + + return ( +
+ {categories.map((category) => ( +
+
+
+ +
+

{category.name}

+
+ +
    + {category.tips.map((tip, index) => ( +
  • + {tip} +
  • + ))} +
+
+ ))} + + +
+ ) +} diff --git a/supabase/migrations/20250227092633_user_management_starter.sql b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/action.ts similarity index 100% rename from supabase/migrations/20250227092633_user_management_starter.sql rename to sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/action.ts diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/page.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/page.tsx new file mode 100644 index 0000000..6774279 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/community-engagement/page.tsx @@ -0,0 +1,110 @@ +"use client" + +import { BentoGrid, BentoGridItem } from "@/app/_components/ui/bento-grid" +import { Bell, Calendar, FileText, MapPin, MessageSquare, Phone, Users, HelpCircle, BarChart3 } from "lucide-react" +import CommunityHeader from "./_components/community-header" +import CrimeAlerts from "./_components/crime-alerts" +import SafetyTips from "./_components/safety-tips" +import CommunityEvents from "./_components/community-events" +import NeighborhoodWatch from "./_components/neighborhood-watch" +import ReportIncident from "./_components/report-incident" +import CrimeStatistics from "./_components/crime-statistics" +import ResourceDirectory from "./_components/resource-directory" +import FAQSection from "./_components/faq-section" +import CommunityFeedback from "./_components/community-feedback" +import CommunityMap from "./_components/community-map" + +export default function CommunityEngagementPage() { + return ( +
+
+ + + + } + colSpan="2" + > + + + + } + rowSpan="2" + > + + + + } + > + + + + } + > + + + + } + > + + + + } + > + + + + } + colSpan="2" + > + + + + } + > + + + + } + > + + + + } + > + + + +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-assignees.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-assignees.tsx new file mode 100644 index 0000000..858e30d --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-assignees.tsx @@ -0,0 +1,69 @@ +import { User } from "lucide-react" +import { Badge } from "@/app/_components/ui/badge" + +export default function CaseAssignees() { + const assignees = [ + { + id: "OFF-1234", + name: "Michael Chen", + role: "Lead Detective", + badge: "ID-5678", + contact: "555-123-4567", + status: "Active", + }, + { + id: "OFF-2345", + name: "Sarah Johnson", + role: "Forensic Specialist", + badge: "ID-6789", + contact: "555-234-5678", + status: "Active", + }, + { + id: "OFF-3456", + name: "Robert Wilson", + role: "Evidence Technician", + badge: "ID-7890", + contact: "555-345-6789", + status: "Active", + }, + { + id: "OFF-4567", + name: "James Rodriguez", + role: "Patrol Officer", + badge: "ID-8901", + contact: "555-456-7890", + status: "Standby", + }, + ] + + return ( +
+ {assignees.map((officer) => ( +
+
+ +
+ +
+
+

{officer.name}

+ + {officer.status} + +
+ +
+ {officer.role} • Badge #{officer.badge} +
+
+
+ ))} + + +
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-documents.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-documents.tsx new file mode 100644 index 0000000..9ccb419 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-documents.tsx @@ -0,0 +1,92 @@ +import { Download, FileText, FilePlus, FileImage, FileSpreadsheet } from "lucide-react" +import { Badge } from "@/app/_components/ui/badge" + +export default function CaseDocuments() { + const documents = [ + { + id: "DOC-3421", + name: "Initial Police Report", + type: "PDF", + size: "1.2 MB", + uploadedBy: "James Rodriguez", + uploadDate: "Apr 15, 2023", + icon: FileText, + }, + { + id: "DOC-3422", + name: "Autopsy Report", + type: "PDF", + size: "3.5 MB", + uploadedBy: "Dr. Lisa Wong", + uploadDate: "Apr 17, 2023", + icon: FileText, + }, + { + id: "DOC-3423", + name: "Crime Scene Photos", + type: "ZIP", + size: "24.7 MB", + uploadedBy: "Robert Wilson", + uploadDate: "Apr 15, 2023", + icon: FileImage, + }, + { + id: "DOC-3424", + name: "Witness Statement - Emily Parker", + type: "DOCX", + size: "285 KB", + uploadedBy: "Michael Chen", + uploadDate: "Apr 20, 2023", + icon: FilePlus, + }, + { + id: "DOC-3425", + name: "Evidence Log", + type: "XLSX", + size: "420 KB", + uploadedBy: "Sarah Johnson", + uploadDate: "Apr 22, 2023", + icon: FileSpreadsheet, + }, + ] + + return ( +
+
+

Case Documents ({documents.length})

+ +
+ +
+ {documents.map((doc) => ( +
+
+ +
+ +
+
+

{doc.name}

+ {doc.type} +
+ +
+ {doc.size} + Uploaded: {doc.uploadDate} + By: {doc.uploadedBy} +
+
+ + +
+ ))} +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-evidence.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-evidence.tsx new file mode 100644 index 0000000..280e859 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-evidence.tsx @@ -0,0 +1,93 @@ +import { FileText, ImageIcon, Package } from "lucide-react" +import { Badge } from "@/app/_components/ui/badge" + +export default function CaseEvidence() { + const evidenceItems = [ + { + id: "EV-4523", + type: "Weapon", + description: "Kitchen knife, 8-inch blade with wooden handle", + dateCollected: "Apr 18, 2023", + status: "Processing", + location: "Evidence Locker B-12", + icon: Package, + }, + { + id: "EV-4524", + type: "Photograph", + description: "Crime scene photos - living room area", + dateCollected: "Apr 15, 2023", + status: "Analyzed", + location: "Digital Storage", + icon: ImageIcon, + }, + { + id: "EV-4525", + type: "Document", + description: "Victim's personal diary", + dateCollected: "Apr 15, 2023", + status: "Analyzed", + location: "Evidence Locker A-7", + icon: FileText, + }, + { + id: "EV-4526", + type: "DNA Sample", + description: "Blood sample from kitchen floor", + dateCollected: "Apr 15, 2023", + status: "Lab Analysis", + location: "Forensic Lab", + icon: Package, + }, + ] + + return ( +
+
+

Evidence Items ({evidenceItems.length})

+ +
+ +
+ {evidenceItems.map((item) => ( +
+
+ +
+ +
+
+

{item.id}

+ {item.type} + + {item.status} + +
+ +

{item.description}

+ +
+ Collected: {item.dateCollected} + Location: {item.location} +
+
+ + +
+ ))} +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-header.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-header.tsx new file mode 100644 index 0000000..2b25031 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-header.tsx @@ -0,0 +1,47 @@ +import { AlertTriangle, Calendar, Clock } from "lucide-react" +import { Badge } from "@/app/_components/ui/badge" +import { Button } from "@/app/_components/ui/button" + +interface CaseHeaderProps { + caseId: string + title: string + status: string + priority: string + dateOpened: string + lastUpdated: string +} + +export default function CaseHeader({ caseId, title, status, priority, dateOpened, lastUpdated }: CaseHeaderProps) { + return ( +
+
+
+

Case #{caseId}

+ + {status} + + + + {priority} + +
+

{title}

+
+
+ + Opened: {dateOpened} +
+
+ + Last updated: {lastUpdated} +
+
+
+ +
+ + +
+
+ ) +} diff --git a/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-notes.tsx b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-notes.tsx new file mode 100644 index 0000000..5a4f3e1 --- /dev/null +++ b/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-incident/_components/case-notes.tsx @@ -0,0 +1,72 @@ +import { User } from "lucide-react" +import { Button } from "@/app/_components/ui/button" +import { Textarea } from "@/app/_components/ui/textarea" + +export default function CaseNotes() { + const notes = [ + { + id: "N-5621", + content: + "Forensic analysis suggests the murder weapon was wiped clean before being discarded. No fingerprints were recovered, but DNA traces were found on the handle.", + author: "Sarah Johnson", + role: "Forensic Specialist", + timestamp: "Apr 22, 2023 • 15:10", + }, + { + id: "N-5620", + content: + "Witness Emily Parker's statement corroborates the timeline established by the medical examiner. Victim was likely killed between 9:00 PM and 11:00 PM on April 14.", + author: "Michael Chen", + role: "Detective", + timestamp: "Apr 20, 2023 • 14:35", + }, + { + id: "N-5619", + content: + "Background check on suspect John Doe shows prior assault charges that were dropped in 2021. Need to follow up with previous complainant.", + author: "Michael Chen", + role: "Detective", + timestamp: "Apr 19, 2023 • 10:22", + }, + { + id: "N-5618", + content: + "Initial canvas of the neighborhood complete. Three potential witnesses identified and scheduled for interviews.", + author: "James Rodriguez", + role: "Patrol Officer", + timestamp: "Apr 16, 2023 • 08:45", + }, + ] + + return ( +
+
+

Case Notes

+ +
+