Skip to content

Commit 88327bf

Browse files
more type safety
1 parent 624e107 commit 88327bf

File tree

12 files changed

+143
-131
lines changed

12 files changed

+143
-131
lines changed

.vscode/tasks.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"type": "eslint",
6+
"problemMatcher": ["$eslint-stylish"],
7+
"label": "eslint: lint whole folder"
8+
},
9+
{
10+
"label": "ESLint",
11+
"type": "shell",
12+
"problemMatcher": "$eslint-stylish",
13+
"command": "pnpm lint",
14+
"windows": {
15+
"command": "pnpm lint"
16+
}
17+
}
18+
]
19+
}

src/app/layout.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import { getUser, getAccount } from '~/server/db/actions';
1212
import type { InitialAuth } from '~/store/auth';
1313
import { Toaster } from '~/components/ui/toaster';
1414
import { ToastManager } from '~/components/providers/toast';
15-
import { cn } from '~/lib/utils';
16-
import { headers } from 'next/headers';
1715

1816
export const metadata = {
1917
title: 'ActivityMap',

src/app/stats/[name]/layout.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,16 @@ const TabsLinkTrigger: React.FC<{
3535
children: React.ReactNode;
3636
className?: string;
3737
}> = ({ href, children, className }) => (
38-
<TabsTrigger value={href} asChild className={className ? className : ''}>
38+
<TabsTrigger value={href} asChild className={className ?? ''}>
3939
<Link href={href}>{children}</Link>
4040
</TabsTrigger>
4141
);
4242

4343
export default function Stats({ children }: { children: React.ReactNode }) {
44-
const { settingsOpen, setSettingsOpen, activeTab, setActiveTab } = useStore(
44+
const { settingsOpen, setSettingsOpen } = useStore(
4545
useShallow((state) => ({
4646
settingsOpen: state.settingsOpen,
4747
setSettingsOpen: state.setSettingsOpen,
48-
setActiveTab: state.setActiveTab,
49-
activeTab: state.activeTab,
5048
})),
5149
);
5250

src/components/map/DownloadControl.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function Download() {
3939
container: container,
4040
center: map.current.getCenter(),
4141
zoom: map.current.getZoom(),
42-
style: map.current.getStyle(),
42+
style: map.current.getStyle() ?? undefined,
4343
bearing: map.current.getBearing(),
4444
pitch: map.current.getPitch(),
4545
interactive: false,

src/components/map/Overlay.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
type IControl,
66
useControl,
77
} from 'react-map-gl/mapbox';
8-
8+
import { type Map as MapboxMap } from 'mapbox-gl';
99
type Config = {
1010
position: ControlPosition;
1111
redraw?: () => void;
@@ -69,7 +69,7 @@ const Overlay = ({ position, children }: OverlayProps) => {
6969
const elem = ctrl.getElement();
7070
if (map === null || elem === null) return;
7171

72-
return createPortal(cloneElement(children, { map }), elem);
72+
return createPortal(cloneElement(children), elem);
7373
};
7474

7575
export default memo(Overlay);

src/components/map/Photo.tsx

+28-28
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ export default function PhotoLayer() {
2525
longitude={photo.location![1]}
2626
latitude={photo.location![0]}
2727
key={photo.unique_id}
28-
zoom={position.zoom}
29-
urls={photo.urls}
30-
sizes={photo.sizes}
28+
urls={photo.urls ?? {}}
29+
sizes={photo.sizes ?? {}}
3130
activity_name={photo.activity_name!}
3231
activity_id={photo.activity_id}
3332
caption={photo.caption ?? undefined}
@@ -45,16 +44,14 @@ function PhotoMarker({
4544
activity_name,
4645
activity_id,
4746
caption,
48-
zoom,
4947
}: {
5048
urls: Record<number, string>;
5149
sizes: Record<number, [number, number]>;
52-
longitude: number;
53-
latitude: number;
50+
longitude?: number;
51+
latitude?: number;
5452
activity_name: string;
5553
activity_id: number;
5654
caption?: string;
57-
zoom: number;
5855
}) {
5956
const photoUrl = Object.values(urls)[0];
6057
const [hover, setHover] = useState(false);
@@ -64,27 +61,30 @@ function PhotoMarker({
6461
}));
6562

6663
return (
67-
<Marker
68-
longitude={longitude}
69-
latitude={latitude}
70-
anchor="center"
71-
style={{ zIndex: hover ? 3 : 2, cursor: 'pointer' }}
72-
onClick={(e) => {
73-
e.originalEvent.stopPropagation();
74-
setSelected([activity_id]);
75-
}}
76-
>
77-
<Avatar
78-
onMouseEnter={() => setHover(true)}
79-
onMouseLeave={() => setHover(false)}
80-
className="size-8 border-2 border-white transition-all hover:size-32 overflow-auto"
64+
longitude &&
65+
latitude && (
66+
<Marker
67+
longitude={longitude}
68+
latitude={latitude}
69+
anchor="center"
70+
style={{ zIndex: hover ? 3 : 2, cursor: 'pointer' }}
71+
onClick={(e) => {
72+
e.originalEvent.stopPropagation();
73+
setSelected([activity_id]);
74+
}}
8175
>
82-
<AvatarImage
83-
src={photoUrl}
84-
alt={caption ?? activity_name}
85-
className="w-full h-full object-cover"
86-
/>
87-
</Avatar>
88-
</Marker>
76+
<Avatar
77+
onMouseEnter={() => setHover(true)}
78+
onMouseLeave={() => setHover(false)}
79+
className="size-8 border-2 border-white transition-all hover:size-32 overflow-auto"
80+
>
81+
<AvatarImage
82+
src={photoUrl}
83+
alt={caption ?? activity_name}
84+
className="w-full h-full object-cover"
85+
/>
86+
</Avatar>
87+
</Marker>
88+
)
8989
);
9090
}

src/components/providers/auth.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import { useEffect } from 'react';
44
import { useSearchParams } from 'next/navigation';
55
import { useShallowStore } from '~/store';
6-
import type { Session } from 'next-auth';
7-
import type { User, Account } from '~/server/db/schema';
86
import type { InitialAuth } from '~/store/auth';
97

108
export function AuthProvider({

src/components/sidebar/Sidebar.tsx

-11
This file was deleted.

src/components/sidebar/filters.tsx

+17-30
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
'use client';
22

3-
import { type ComponentType } from 'react';
43
import { useEffect } from 'react';
54

6-
import { type LucideProps, MoreHorizontal } from 'lucide-react';
5+
import { MoreHorizontal } from 'lucide-react';
76

87
import { useShallowStore } from '~/store';
98

@@ -43,17 +42,6 @@ import { cn } from '~/lib/utils';
4342
import { binaryFilters, inequalityFilters } from '~/settings/filter';
4443
import { Checkbox } from '../ui/checkbox';
4544
import { type SportType } from '~/server/db/schema';
46-
import { type CheckedState } from '@radix-ui/react-checkbox';
47-
48-
type DropdownProps = {
49-
title: string;
50-
values: Record<SportType, CheckedState>;
51-
Icon: ComponentType<LucideProps>;
52-
color: string;
53-
onToggle: () => void;
54-
onChange: (value: SportType) => void;
55-
active: boolean;
56-
};
5745

5846
export function CategoryFilter() {
5947
const { sportType, sportGroup, setSportGroup, setSportType } =
@@ -69,6 +57,19 @@ export function CategoryFilter() {
6957
);
7058

7159
useEffect(() => {
60+
const doSingleClickThing = () => {
61+
if (key) setSportGroup((group) => ({ ...group, [key]: !group[key] }));
62+
};
63+
64+
const doDoubleClickThing = () => {
65+
if (key)
66+
setSportGroup(
67+
(group) =>
68+
Object.fromEntries(
69+
Object.keys(group).map((k) => [k, k === key]),
70+
) as Record<keyof typeof categorySettings, boolean>,
71+
);
72+
};
7273
let singleClickTimer: NodeJS.Timeout;
7374
if (clicks === 1) {
7475
singleClickTimer = setTimeout(function () {
@@ -80,21 +81,7 @@ export function CategoryFilter() {
8081
setClicks(0);
8182
}
8283
return () => clearTimeout(singleClickTimer);
83-
}, [clicks]);
84-
85-
const doSingleClickThing = () => {
86-
if (key) setSportGroup((group) => ({ ...group, [key]: !group[key] }));
87-
};
88-
89-
const doDoubleClickThing = () => {
90-
if (key)
91-
setSportGroup(
92-
(group) =>
93-
Object.fromEntries(
94-
Object.keys(group).map((k) => [k, k === key]),
95-
) as Record<keyof typeof categorySettings, boolean>,
96-
);
97-
};
84+
}, [clicks, key, setSportGroup]);
9885

9986
return (
10087
<SidebarMenu>
@@ -184,7 +171,7 @@ export function InequalityFilter({
184171
...prev,
185172
[name]: input === '' ? undefined : { value: transformed, operator },
186173
}));
187-
}, [operator, value, input, name]);
174+
}, [operator, value, input, name, setValues]);
188175

189176
return (
190177
<SidebarMenuItem>
@@ -279,7 +266,7 @@ export function BinaryFilter({ name }: { name: keyof typeof binaryFilters }) {
279266
{binaryFilters[name].label}
280267
</label>
281268
<Checkbox
282-
checked={binary === undefined ? 'indeterminate' : binary}
269+
checked={binary ?? 'indeterminate'}
283270
onCheckedChange={handleChange}
284271
/>
285272
</SidebarMenuItem>

src/components/sidebar/user.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
Info,
99
} from 'lucide-react';
1010

11-
import Link from 'next/link';
1211
import { signIn, signOut } from 'next-auth/react';
1312

1413
import { useShallowStore } from '~/store';
@@ -28,19 +27,18 @@ import { Avatar, AvatarFallback, AvatarImage } from '~/components/ui/avatar';
2827
import * as React from 'react';
2928
import Image from 'next/image';
3029
import { cn } from '~/lib/utils';
31-
import { User2 } from 'lucide-react';
3230
import { checkWebhookStatus } from '~/server/strava/actions';
3331
import { env } from '~/env';
3432

3533
export function UserSettings() {
36-
const { user, loading, account, loadFromStrava, isInitialized } =
37-
useShallowStore((state) => ({
34+
const { user, loading, loadFromStrava, isInitialized } = useShallowStore(
35+
(state) => ({
3836
user: state.user,
3937
loading: state.loading,
40-
account: state.account,
4138
loadFromStrava: state.loadFromStrava,
4239
isInitialized: state.isInitialized,
43-
}));
40+
}),
41+
);
4442

4543
const isDevelopment = env.NEXT_PUBLIC_ENV === 'development';
4644

0 commit comments

Comments
 (0)