Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions resources/js/components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function Table({ className, ...props }: React.ComponentProps<"table">) {
>
<table
data-slot="table"
className={cn("w-full caption-bottom text-sm", className)}
className={cn("w-full caption-top text-sm", className)}
{...props}
/>
</div>
Expand Down Expand Up @@ -96,19 +96,14 @@ function TableCaption({
return (
<caption
data-slot="table-caption"
className={cn("text-muted-foreground mt-4 text-sm", className)}
className={cn("text-muted-foreground my-4 text-sm", className)}
{...props}
/>
)
}

export {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
TableCaption,
Table, TableBody, TableCaption, TableCell, TableFooter,
TableHead, TableHeader, TableRow
}

2 changes: 1 addition & 1 deletion resources/js/components/usage-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type ChartData = {
};

export const UsageChart = ({ chart_data }: { chart_data: ChartData[] }) => (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<ChartContainer config={chartConfig} className="h-full min-h-[200px] w-full">
<BarChart accessibilityLayer data={chart_data}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} tickFormatter={(value) => value.slice(0, 3)} />
Expand Down
51 changes: 38 additions & 13 deletions resources/js/pages/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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<typeof UsageChart>) {
function deleteGeocode(id: number) {
router.post(`/geocodes/delete/${id}`);
Expand All @@ -52,30 +59,47 @@ export default function Dashboard({
<Head title="Dashboard" />
<div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
<div className="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border">
<UsageChart chart_data={chart_data} />p
<div className="border-sidebar-border/70 dark:border-sidebar-border relative grid grid-rows-[min-content] overflow-hidden rounded-xl border">
<TableCaption>Total requests by month</TableCaption>
<UsageChart chart_data={chart_data} />
</div>
<div className="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border">
<PlaceholderPattern className="absolute inset-0 size-full stroke-neutral-900/20 dark:stroke-neutral-100/20" />
<div className="border-sidebar-border/70 dark:border-sidebar-border relative overflow-hidden rounded-xl border">
<Table>
<TableCaption>Monthly requests by application</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Application</TableHead>
<TableHead className="text-right">Total</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{applications.map(({ application, total }) => (
<TableRow key={application}>
<TableCell>{application}</TableCell>
<TableCell className="text-right">{total.toLocaleString()}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<div className="border-sidebar-border/70 dark:border-sidebar-border relative aspect-video overflow-hidden rounded-xl border">
<div className="border-sidebar-border/70 dark:border-sidebar-border relative overflow-hidden rounded-xl border">
<Table>
<TableCaption>Request counts by domain</TableCaption>
<TableCaption>Monthly requests by domain</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Domain</TableHead>
<TableHead className="text-right">Total</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{domains.map(({ domain, total }) => (
{domains.map(({ domain, label, total }) => (
<TableRow key={domain}>
<TableCell>
<a className="cursor-pointer hover:underline" href={`https://${domain}/`} target="_blank">
{domain}
{label}
</a>
</TableCell>
<TableCell className="text-right">{total}</TableCell>
<TableCell className="text-right">{total.toLocaleString()}</TableCell>
</TableRow>
))}
</TableBody>
Expand Down Expand Up @@ -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',
})}
>
<span className="max-w-full truncate">{geocode.application}</span>
Expand Down
23 changes: 19 additions & 4 deletions resources/js/pages/welcome.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<Map>(null);

const { auth } = usePage<SharedData>().props;
const [location, setLocation] = useState<ComponentProps<typeof Location>>();

const handleSearch = async (e: React.FormEvent<HTMLFormElement>) => {
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,
Expand Down Expand Up @@ -98,7 +107,13 @@ export default function Welcome({ mapbox }: { mapbox: string }) {
)}
</div>
<div className="relative flex-grow md:w-3/4">
<MapContainer center={[0, 0]} zoom={2} minZoom={2} style={{ bottom: 0, position: 'absolute', top: 0, width: '100%' }}>
<MapContainer
center={[0, 0]}
minZoom={2}
ref={mapRef}
style={{ bottom: 0, position: 'absolute', top: 0, width: '100%' }}
zoom={2}
>
<TileLayer
attribution='Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
url={`https://api.mapbox.com/styles/v1/mapbox/${isDarkMode ? 'dark' : 'streets'}-v11/tiles/{z}/{x}/{y}?access_token=${mapbox}`}
Expand Down
22 changes: 20 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,26 @@
$geocode->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))
Expand All @@ -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');

Expand Down