diff --git a/resources/js/components/ui/table.tsx b/resources/js/components/ui/table.tsx index 5513a5c..853094c 100644 --- a/resources/js/components/ui/table.tsx +++ b/resources/js/components/ui/table.tsx @@ -10,7 +10,7 @@ function Table({ className, ...props }: React.ComponentProps<"table">) { > @@ -96,19 +96,14 @@ function TableCaption({ return (
) } export { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, - TableCaption, + Table, TableBody, TableCaption, TableCell, TableFooter, + TableHead, TableHeader, TableRow } + diff --git a/resources/js/components/usage-chart.tsx b/resources/js/components/usage-chart.tsx index 3707aa7..e873050 100644 --- a/resources/js/components/usage-chart.tsx +++ b/resources/js/components/usage-chart.tsx @@ -17,7 +17,7 @@ type ChartData = { }; export const UsageChart = ({ chart_data }: { chart_data: ChartData[] }) => ( - + value.slice(0, 3)} /> diff --git a/resources/js/pages/dashboard.tsx b/resources/js/pages/dashboard.tsx index 23d4cf3..9f1bcda 100644 --- a/resources/js/pages/dashboard.tsx +++ b/resources/js/pages/dashboard.tsx @@ -2,7 +2,6 @@ import { ComponentProps } from 'react'; import { Head, router } from '@inertiajs/react'; -import { PlaceholderPattern } from '@/components/ui/placeholder-pattern'; import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { UsageChart } from '@/components/usage-chart'; import AppLayout from '@/layouts/app-layout'; @@ -30,18 +29,26 @@ type Geocode = { bounds: boolean; }; +type Application = { + application: string; + total: number; +}; + type Domain = { domain: string; + label: string; total: number; }; export default function Dashboard({ - geocodes, - domains, + applications, chart_data, + domains, + geocodes, }: { - geocodes: Geocode[]; + applications: Application[]; domains: Domain[]; + geocodes: Geocode[]; } & ComponentProps) { function deleteGeocode(id: number) { router.post(`/geocodes/delete/${id}`); @@ -52,15 +59,32 @@ export default function Dashboard({
-
- p +
+ Total requests by month +
-
- +
+ + Monthly requests by application + + + Application + Total + + + + {applications.map(({ application, total }) => ( + + {application} + {total.toLocaleString()} + + ))} + +
-
+
- Request counts by domain + Monthly requests by domain Domain @@ -68,14 +92,14 @@ export default function Dashboard({ - {domains.map(({ domain, total }) => ( + {domains.map(({ domain, label, total }) => ( - {domain} + {label} - {total} + {total.toLocaleString()} ))} @@ -104,6 +128,7 @@ export default function Dashboard({ className={clsx('mr-2 rounded px-2 py-1 font-mono text-xs font-bold text-white uppercase', { 'bg-indigo-600': geocode.application === 'tsml-ui', 'bg-neutral-600': geocode.application === 'geo', + 'bg-rose-600': geocode.application === 'tsml', })} > {geocode.application} diff --git a/resources/js/pages/welcome.tsx b/resources/js/pages/welcome.tsx index 4d2851d..a7d0675 100644 --- a/resources/js/pages/welcome.tsx +++ b/resources/js/pages/welcome.tsx @@ -1,8 +1,8 @@ -import { ComponentProps, useEffect, useState } from 'react'; +import { ComponentProps, useEffect, useRef, useState } from 'react'; import { Head, Link, usePage } from '@inertiajs/react'; import clsx from 'clsx'; -import { divIcon, Point } from 'leaflet'; +import { divIcon, type Map, Point } from 'leaflet'; import 'leaflet/dist/leaflet.css'; import { SquareArrowOutUpRightIcon } from 'lucide-react'; import { MapContainer, Marker, TileLayer, useMap } from 'react-leaflet'; @@ -15,21 +15,30 @@ const buttonClass = 'rounded border hover:border-neutral-400 dark:border-neutral export default function Welcome({ mapbox }: { mapbox: string }) { const isDarkMode = useDarkMode(); + const mapRef = useRef(null); + const { auth } = usePage().props; const [location, setLocation] = useState>(); const handleSearch = async (e: React.FormEvent) => { e.preventDefault(); const data = new FormData(e.currentTarget); + + const [west, south, east, north] = mapRef.current?.getBounds().toBBoxString().split(',') || []; + const response = await fetch( `/api/geocode?${new URLSearchParams({ search: `${data.get('search')}`, application: 'geo', referrer: window.location.href, + north, + south, + east, + west, })}`, ); const { results } = await response.json(); - if (results) { + if (results.length) { setLocation({ formatted_address: results[0].formatted_address, location: results[0].geometry.location, @@ -98,7 +107,13 @@ export default function Welcome({ mapbox }: { mapbox: string }) { )}
- + bounds = $geocode->north && $geocode->south && $geocode->east && $geocode->west; return $geocode; }); + + $decoded_domains = [ + 'meetingfinderstorage.z13.web.core.windows.net' => 'CA Meeting Finder App', + ]; + $domains = Geocode::select('domain', DB::raw('count(*) as total')) + ->where('created_at', '>', Carbon::now()->startOfMonth()->subMonths(1)) ->groupBy('domain') ->orderBy('total', 'desc') + ->limit(10) + ->get() + ->map(function ($item) use ($decoded_domains) { + $item->label = $decoded_domains[$item->domain] ?? $item->domain; + return $item; + }); + $applications = Geocode::select('application', DB::raw('count(*) as total')) + ->where('created_at', '>', Carbon::now()->startOfMonth()->subMonths(1)) + ->groupBy('application') + ->orderBy('total', 'desc') + ->limit(10) ->get(); $dates = Geocode::select(['created_at']) ->where('created_at', '>', Carbon::now()->startOfMonth()->subMonths(5)) @@ -50,9 +67,10 @@ return compact('month', 'geocodes'); }, [5, 4, 3, 2, 1, 0]); return Inertia::render('dashboard', [ - 'geocodes' => $geocodes, + 'applications' => $applications, + 'chart_data' => $chart_data, 'domains' => $domains, - 'chart_data' => $chart_data + 'geocodes' => $geocodes, ]); })->name('dashboard');