├── lib ├── clientUtils.js ├── utils.js ├── cleanupService.js ├── sse.js ├── agentchat-utils.ts ├── version.js └── notifications.js ├── .eslintrc.json ├── 1024.png ├── 180.png ├── 192.png ├── 512.png ├── Images ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── db.jpg ├── Hero.jpg ├── dash.jpg ├── push.jpg ├── tags.jpg ├── tpms.jpg ├── alert.JPG ├── apikey.png ├── hero2.png ├── viewer.jpg ├── app_icon.png ├── blueiris.png ├── insights.jpg └── liveview.jpg ├── app ├── 1024.png ├── 180.png ├── 192.png ├── 512.png ├── favicon.ico ├── apple-icon.png ├── fonts │ ├── GeistVF.woff │ └── GeistMonoVF.woff ├── page.jsx ├── api │ ├── check-update │ │ └── route.js │ ├── health-check │ │ └── route.js │ ├── _startup.js │ ├── verify-key │ │ └── route.js │ ├── mqtt │ │ └── brokers │ │ │ ├── route.js │ │ │ └── [id] │ │ │ └── route.js │ ├── notifications │ │ └── test │ │ │ └── route.js │ ├── verify-session │ │ └── route.js │ ├── sse │ │ └── route.js │ └── verify-whitelist │ │ └── route.js ├── training │ ├── page.jsx │ └── TrainingControl.jsx ├── backfill │ ├── page.jsx │ └── BackfillButton.jsx ├── download │ └── page.jsx ├── flagged │ └── page.jsx ├── settings │ └── page.jsx ├── manifest.js ├── dashboard │ ├── page.jsx │ ├── CameraSelect.jsx │ └── TimeSelect.jsx ├── database │ └── page.jsx ├── logs │ ├── LogMessage.jsx │ └── page.jsx ├── images │ └── [...path] │ │ └── route.js ├── known_plates │ └── page.jsx ├── components │ └── ui │ │ └── tooltip.jsx ├── notifications │ └── page.jsx ├── update │ └── BackfillButton.jsx ├── live_feed │ ├── viewer │ │ └── page.jsx │ └── page.jsx ├── globals.css ├── favicon.svg └── help │ └── page.jsx ├── public ├── 1024.png ├── 180.png ├── 512.png ├── alpr.jpg ├── icon.png ├── fallback.jpg ├── placeholder.jpg ├── test-plate.jpg ├── license-plate.ico ├── icon512_maskable.png ├── icon512_rounded.png ├── splash_screens │ ├── 10.2__iPad_portrait.png │ ├── 10.2__iPad_landscape.png │ ├── iPhone_16_Pro_portrait.png │ ├── 10.5__iPad_Air_landscape.png │ ├── 10.5__iPad_Air_portrait.png │ ├── 10.9__iPad_Air_landscape.png │ ├── 10.9__iPad_Air_portrait.png │ ├── 11__iPad_Pro_M4_portrait.png │ ├── 12.9__iPad_Pro_landscape.png │ ├── 12.9__iPad_Pro_portrait.png │ ├── 13__iPad_Pro_M4_portrait.png │ ├── 8.3__iPad_Mini_landscape.png │ ├── 8.3__iPad_Mini_portrait.png │ ├── iPhone_16_Pro_landscape.png │ ├── 11__iPad_Pro_M4_landscape.png │ ├── 13__iPad_Pro_M4_landscape.png │ ├── iPhone_16_Pro_Max_landscape.png │ ├── iPhone_16_Pro_Max_portrait.png │ ├── iPhone_11__iPhone_XR_portrait.png │ ├── iPhone_11__iPhone_XR_landscape.png │ ├── 11__iPad_Pro__10.5__iPad_Pro_portrait.png │ ├── 11__iPad_Pro__10.5__iPad_Pro_landscape.png │ ├── iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png │ ├── iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png │ ├── 4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png │ ├── 4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png │ ├── iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png │ ├── iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png │ ├── iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png │ ├── iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png │ ├── 9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png │ ├── iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png │ ├── 9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png │ ├── iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png │ ├── iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png │ ├── iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png │ ├── iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png │ ├── iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png │ ├── iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png │ ├── iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png │ ├── iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png │ └── iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png ├── vercel.svg ├── window.svg ├── file.svg ├── manifest.json ├── globe.svg └── next.svg ├── postcss.config.mjs ├── components ├── ui │ ├── aspect-ratio.jsx │ ├── skeleton.jsx │ ├── collapsible.jsx │ ├── label.jsx │ ├── separator.jsx │ ├── textarea.jsx │ ├── progress.jsx │ ├── toaster.jsx │ ├── checkbox.jsx │ ├── sonner.jsx │ ├── slider.jsx │ ├── hover-card.jsx │ ├── avatar.jsx │ ├── tooltip.jsx │ ├── input.jsx │ ├── switch.jsx │ ├── badge.jsx │ ├── popover.jsx │ ├── radio-group.jsx │ ├── toggle-group.jsx │ ├── scroll-area.jsx │ ├── toggle-switch.jsx │ ├── toggle.jsx │ ├── alert.jsx │ ├── card.jsx │ ├── accordion.jsx │ ├── resizable.jsx │ ├── tabs.jsx │ ├── input-otp.jsx │ ├── button.jsx │ ├── breadcrumb.jsx │ ├── table.jsx │ ├── drawer.jsx │ ├── pagination.jsx │ ├── calendar.jsx │ ├── dialog.jsx │ ├── form.jsx │ ├── alert-dialog.jsx │ └── sheet.jsx ├── icons │ └── tpms.jsx ├── layout │ ├── MainLayout.jsx │ ├── BasicTitle.jsx │ ├── LiveFeedNav.jsx │ └── TitleNav.jsx ├── TrainingHandler.jsx ├── MetricsHandler.jsx ├── ThemeToggle.jsx ├── chat │ ├── ChatContext.jsx │ └── ChatButton.jsx ├── PlateImage.jsx ├── LiveFeedTable.jsx ├── TestNotificationButton.jsx ├── ImageViewer.jsx └── debugTable.jsx ├── .dockerignore ├── jsconfig.json ├── next.config.js ├── components.json ├── hooks ├── use-mobile.jsx └── use-toast.js ├── tsconfig.json ├── docker-compose.without-database.yml ├── .gitignore ├── docker-compose-dbonly.yml ├── LICENSE ├── test-mqtt.js ├── example.json ├── Dockerfile ├── json-dump-example.json ├── docker-compose.yml ├── logging └── logger.js ├── CHANGELOG.md ├── tailwind.config.js └── package.json /lib/clientUtils.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/1024.png -------------------------------------------------------------------------------- /180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/180.png -------------------------------------------------------------------------------- /192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/192.png -------------------------------------------------------------------------------- /512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/512.png -------------------------------------------------------------------------------- /Images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/1.png -------------------------------------------------------------------------------- /Images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/2.png -------------------------------------------------------------------------------- /Images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/3.png -------------------------------------------------------------------------------- /Images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/4.png -------------------------------------------------------------------------------- /Images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/5.png -------------------------------------------------------------------------------- /Images/db.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/db.jpg -------------------------------------------------------------------------------- /app/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/1024.png -------------------------------------------------------------------------------- /app/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/180.png -------------------------------------------------------------------------------- /app/192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/192.png -------------------------------------------------------------------------------- /app/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/512.png -------------------------------------------------------------------------------- /Images/Hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/Hero.jpg -------------------------------------------------------------------------------- /Images/dash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/dash.jpg -------------------------------------------------------------------------------- /Images/push.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/push.jpg -------------------------------------------------------------------------------- /Images/tags.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/tags.jpg -------------------------------------------------------------------------------- /Images/tpms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/tpms.jpg -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /public/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/1024.png -------------------------------------------------------------------------------- /public/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/180.png -------------------------------------------------------------------------------- /public/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/512.png -------------------------------------------------------------------------------- /public/alpr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/alpr.jpg -------------------------------------------------------------------------------- /public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/icon.png -------------------------------------------------------------------------------- /Images/alert.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/alert.JPG -------------------------------------------------------------------------------- /Images/apikey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/apikey.png -------------------------------------------------------------------------------- /Images/hero2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/hero2.png -------------------------------------------------------------------------------- /Images/viewer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/viewer.jpg -------------------------------------------------------------------------------- /app/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/apple-icon.png -------------------------------------------------------------------------------- /Images/app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/app_icon.png -------------------------------------------------------------------------------- /Images/blueiris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/blueiris.png -------------------------------------------------------------------------------- /Images/insights.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/insights.jpg -------------------------------------------------------------------------------- /Images/liveview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/Images/liveview.jpg -------------------------------------------------------------------------------- /public/fallback.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/fallback.jpg -------------------------------------------------------------------------------- /app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /public/placeholder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/placeholder.jpg -------------------------------------------------------------------------------- /public/test-plate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/test-plate.jpg -------------------------------------------------------------------------------- /public/license-plate.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/license-plate.ico -------------------------------------------------------------------------------- /app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /public/icon512_maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/icon512_maskable.png -------------------------------------------------------------------------------- /public/icon512_rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/icon512_rounded.png -------------------------------------------------------------------------------- /public/splash_screens/10.2__iPad_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.2__iPad_portrait.png -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/splash_screens/10.2__iPad_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.2__iPad_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Pro_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Pro_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/10.5__iPad_Air_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.5__iPad_Air_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/10.5__iPad_Air_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.5__iPad_Air_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/10.9__iPad_Air_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.9__iPad_Air_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/10.9__iPad_Air_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/10.9__iPad_Air_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/11__iPad_Pro_M4_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/11__iPad_Pro_M4_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/12.9__iPad_Pro_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/12.9__iPad_Pro_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/12.9__iPad_Pro_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/12.9__iPad_Pro_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/13__iPad_Pro_M4_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/13__iPad_Pro_M4_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/8.3__iPad_Mini_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/8.3__iPad_Mini_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/8.3__iPad_Mini_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/8.3__iPad_Mini_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Pro_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Pro_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/11__iPad_Pro_M4_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/11__iPad_Pro_M4_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/13__iPad_Pro_M4_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/13__iPad_Pro_M4_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Pro_Max_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Pro_Max_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Pro_Max_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Pro_Max_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_11__iPhone_XR_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_11__iPhone_XR_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_11__iPhone_XR_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_11__iPhone_XR_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_portrait.png -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/11__iPad_Pro__10.5__iPad_Pro_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_11_Pro_Max__iPhone_XS_Max_portrait.png -------------------------------------------------------------------------------- /components/ui/aspect-ratio.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/4__iPhone_SE__iPod_touch_5th_generation_and_later_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_14_Plus__iPhone_13_Pro_Max__iPhone_12_Pro_Max_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16__iPhone_15_Pro__iPhone_15__iPhone_14_Pro_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_8__iPhone_7__iPhone_6s__iPhone_6__4.7__iPhone_SE_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_8_Plus__iPhone_7_Plus__iPhone_6s_Plus__iPhone_6_Plus_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_14__iPhone_13_Pro__iPhone_13__iPhone_12_Pro__iPhone_12_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_landscape.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_13_mini__iPhone_12_mini__iPhone_11_Pro__iPhone_XS__iPhone_X_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_portrait.png -------------------------------------------------------------------------------- /public/splash_screens/iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algertc/ALPR-Database/HEAD/public/splash_screens/iPhone_16_Plus__iPhone_15_Pro_Max__iPhone_15_Plus__iPhone_14_Pro_Max_landscape.png -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | 3 | # Not needed as we are bundling the whole app 4 | node_modules 5 | # Log files 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | .next 13 | .git 14 | install.sh 15 | update.sh 16 | 17 | config/* 18 | logs/* 19 | auth/* 20 | storage/* 21 | -------------------------------------------------------------------------------- /components/ui/skeleton.jsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }) { 7 | return ( 8 | (
) 11 | ); 12 | } 13 | 14 | export { Skeleton } 15 | -------------------------------------------------------------------------------- /components/icons/tpms.jsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import TPMSIcon from "/public/tpms.svg"; 3 | 4 | const TPMS = ({ size = 20 }) => { 5 | return ( 6 |
7 | TPMS Icon 8 |
9 | ); 10 | }; 11 | 12 | export default TPMS; 13 | -------------------------------------------------------------------------------- /components/layout/MainLayout.jsx: -------------------------------------------------------------------------------- 1 | import { Sidebar } from "@/components/Sidebar"; 2 | 3 | export default function DashboardLayout({ children }) { 4 | return ( 5 |
6 | 7 |
{children}
8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /app/page.jsx: -------------------------------------------------------------------------------- 1 | import { getPlateReads } from "@/lib/db"; 2 | import PlateTable from "@/components/PlateTable"; 3 | import { ThemeToggle } from "@/components/ThemeToggle"; 4 | import DashboardLayout from "@/components/layout/MainLayout"; 5 | import { redirect } from "next/navigation"; 6 | 7 | export default async function Home() { 8 | redirect("/dashboard"); 9 | } 10 | -------------------------------------------------------------------------------- /public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/ui/collapsible.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["./*"] 6 | }, 7 | "jsx": "react-jsx", 8 | "module": "CommonJS", 9 | "target": "ES6" 10 | }, 11 | "include": [ 12 | "**/*.js", 13 | "**/*.jsx", 14 | "**/*.ts", 15 | "**/*.tsx", 16 | "auth.json", 17 | "next.config.js", 18 | "middleware.js" 19 | ], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /app/api/check-update/route.js: -------------------------------------------------------------------------------- 1 | import { checkUpdateStatus } from "@/lib/db"; 2 | import { NextResponse } from "next/server"; 3 | 4 | export async function GET() { 5 | try { 6 | const updateStatus = await checkUpdateStatus(); 7 | return NextResponse.json({ updateRequired: !updateStatus }); 8 | } catch (error) { 9 | console.error("Error checking update status:", error); 10 | return NextResponse.json({ updateRequired: false }); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/training/page.jsx: -------------------------------------------------------------------------------- 1 | import { TrainingControl } from "./TrainingControl"; 2 | 3 | export default function TrainingPage() { 4 | return ( 5 |
6 |
7 |
8 |

Training Data Test

9 |
10 | 11 |
12 |
13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | import { clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | 8 | export function formatTimeRange(hour, timeFormat) { 9 | if (timeFormat === 24) { 10 | return `${String(hour).padStart(2, "0")}:00`; 11 | } 12 | 13 | const period = hour >= 12 ? "PM" : "AM"; 14 | const adjustedHour = hour % 12 || 12; 15 | return `${adjustedHour}:00 ${period}`; 16 | } 17 | -------------------------------------------------------------------------------- /app/api/health-check/route.js: -------------------------------------------------------------------------------- 1 | // app/api/health-check/route.js 2 | import { getPool } from "@/lib/db"; 3 | 4 | export async function GET() { 5 | try { 6 | const pool = await getPool(); 7 | const client = await pool.connect(); 8 | await client.query("SELECT 1"); 9 | client.release(); 10 | return Response.json({ status: "ok" }); 11 | } catch (error) { 12 | return Response.json( 13 | { status: "error", message: error.message }, 14 | { status: 500 } 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | 3 | const nextConfig = { 4 | outputFileTracingIncludes: { 5 | "/**": [ 6 | "/.next", 7 | "/public", 8 | "/app", 9 | "/lib", 10 | "/components", 11 | "/config", 12 | "/middleware.js", 13 | "/hooks", 14 | "/auth", 15 | "/package.json", 16 | ], 17 | }, 18 | experimental: { 19 | serverActions: { 20 | bodySizeLimit: "8mb", 21 | }, 22 | }, 23 | }; 24 | 25 | module.exports = nextConfig; 26 | -------------------------------------------------------------------------------- /app/backfill/page.jsx: -------------------------------------------------------------------------------- 1 | import { BackfillButton } from "./BackfillButton"; 2 | import { dbBackfill } from "@/app/actions"; 3 | 4 | export const dynamic = "force-dynamic"; 5 | 6 | export default async function BackfillPage() { 7 | return ( 8 |
9 |

10 | Backfill Occurrence Counts to New Column in Plates Table 11 |

12 | 13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": false, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "app/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } 22 | -------------------------------------------------------------------------------- /app/download/page.jsx: -------------------------------------------------------------------------------- 1 | import DashboardLayout from "@/components/layout/MainLayout"; 2 | import TitleNavbar from "@/components/layout/TitleNav"; 3 | 4 | export default function DownloadPage() { 5 | return ( 6 | 7 | 8 |
9 |

Download

10 |

Coming soon...

11 |
12 |
13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /components/ui/label.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva } from "class-variance-authority"; 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef(({ className, ...props }, ref) => ( 14 | 15 | )) 16 | Label.displayName = LabelPrimitive.Root.displayName 17 | 18 | export { Label } 19 | -------------------------------------------------------------------------------- /hooks/use-mobile.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange); 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /app/flagged/page.jsx: -------------------------------------------------------------------------------- 1 | import { getFlagged } from "@/app/actions"; 2 | import { FlaggedPlatesTable } from "@/components/FlaggedPlatesTable"; 3 | import DashboardLayout from "@/components/layout/MainLayout"; 4 | import BasicTitle from "@/components/layout/BasicTitle"; 5 | 6 | export const dynamic = "force-dynamic"; 7 | 8 | export default async function FlaggedPlatesPage() { 9 | const flaggedPlates = await getFlagged(); 10 | 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme_color": "#ffffff", 3 | "background_color": "#09090b", 4 | "icons": [ 5 | { 6 | "src": "/192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/1024.png", 12 | "sizes": "1024x1024", 13 | "type": "image/png", 14 | "purpose": "any maskable" 15 | } 16 | ], 17 | "orientation": "any", 18 | "display": "standalone", 19 | "dir": "auto", 20 | "lang": "en-US", 21 | "name": "ALPR Database", 22 | "short_name": "ALPR", 23 | "start_url": "/", 24 | "scope": "/", 25 | "description": "algertc/alpr-database" 26 | } 27 | -------------------------------------------------------------------------------- /app/settings/page.jsx: -------------------------------------------------------------------------------- 1 | import SettingsForm from "./SettingsForm"; 2 | import { getSettings } from "@/app/actions"; 3 | import { getAuthConfig } from "@/lib/auth"; 4 | 5 | export const dynamic = "force-dynamic"; 6 | export const revalidate = 0; 7 | 8 | export default async function SettingsPage() { 9 | const [settings, authConfig] = await Promise.all([ 10 | getSettings(), 11 | getAuthConfig(), 12 | ]); 13 | 14 | if (!settings) { 15 | throw new Error("Failed to load settings"); 16 | } 17 | 18 | return ( 19 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /app/manifest.js: -------------------------------------------------------------------------------- 1 | export default function manifest() { 2 | return { 3 | theme_color: "#000000", 4 | background_color: "#09090b", 5 | icons: { 6 | icon: [ 7 | { 8 | url: "/1024.png", 9 | sizes: "1024x1024", 10 | type: "image/png", 11 | purpose: "any", 12 | }, 13 | ], 14 | apple: [{ url: "/1024.png" }], 15 | }, 16 | orientation: "any", 17 | display: "standalone", 18 | dir: "auto", 19 | lang: "en-US", 20 | name: "ALPR Database", 21 | short_name: "ALPR", 22 | start_url: "/", 23 | scope: "/", 24 | description: "algertc/alpr-database", 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /components/TrainingHandler.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect } from "react"; 4 | import { processTrainingData } from "@/app/actions"; 5 | 6 | export function TrainingDataHandler() { 7 | useEffect(() => { 8 | // Simple function to trigger training processing 9 | const triggerTrainingProcess = async () => { 10 | try { 11 | await processTrainingData(); 12 | } catch (error) { 13 | console.error("Error triggering training process:", error); 14 | } 15 | }; 16 | 17 | // Run with a slight delay to avoid blocking page load 18 | const timer = setTimeout(triggerTrainingProcess, 2000); 19 | return () => clearTimeout(timer); 20 | }, []); 21 | 22 | return null; 23 | } 24 | -------------------------------------------------------------------------------- /components/ui/separator.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Separator = React.forwardRef(( 9 | { className, orientation = "horizontal", decorative = true, ...props }, 10 | ref 11 | ) => ( 12 | 22 | )) 23 | Separator.displayName = SeparatorPrimitive.Root.displayName 24 | 25 | export { Separator } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "noEmit": true, 9 | "incremental": true, 10 | "module": "esnext", 11 | "esModuleInterop": true, 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./*"] 19 | }, 20 | "plugins": [ 21 | { 22 | "name": "next" 23 | } 24 | ] 25 | }, 26 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /app/dashboard/page.jsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from "react"; 2 | import DashboardLayout from "@/components/layout/MainLayout"; 3 | import DashboardMetrics from "./DashboardMetrics"; 4 | import { DashboardSkeleton } from "@/components/DashboardSkeleton"; 5 | import { MetricsHandler } from "@/components/MetricsHandler"; 6 | import { TrainingDataHandler } from "@/components/TrainingHandler"; 7 | 8 | export default function Dashboard() { 9 | return ( 10 | 11 |
12 | }> 13 | 14 | 15 | 16 | 17 |
18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /components/ui/textarea.jsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Textarea = React.forwardRef(({ className, ...props }, ref) => { 6 | return ( 7 | (