Skip to content

Commit 0eb0087

Browse files
authored
feat: Use dynamic page titles (#43)
Updates the incident details page to set the page title to INC-2001 • Firetower, for easier tab identification. Also removes the use of forwardRef in favor of the new React 19 ref prop.
1 parent 65aeb3c commit 0eb0087

File tree

4 files changed

+44
-41
lines changed

4 files changed

+44
-41
lines changed

frontend/src/components/Card.tsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ const card = cva([
1111

1212
interface CardProps
1313
extends React.HTMLAttributes<HTMLDivElement>,
14-
VariantProps<typeof card> {}
14+
VariantProps<typeof card> {
15+
ref?: React.Ref<HTMLDivElement>;
16+
}
1517

16-
const CardRoot = React.forwardRef<HTMLDivElement, CardProps>(
17-
({className, ...props}, ref) => (
18-
<div ref={ref} className={cn(card({className}))} {...props} />
19-
)
18+
const CardRoot = ({className, ref, ...props}: CardProps) => (
19+
<div ref={ref} className={cn(card({className}))} {...props} />
2020
);
21-
CardRoot.displayName = 'Card';
2221

2322
const title = cva(['text-lg', 'font-semibold', 'mb-space-xl', 'text-content-headings'], {
2423
variants: {
@@ -37,16 +36,15 @@ const title = cva(['text-lg', 'font-semibold', 'mb-space-xl', 'text-content-head
3736

3837
interface TitleProps
3938
extends React.HTMLAttributes<HTMLHeadingElement>,
40-
VariantProps<typeof title> {}
39+
VariantProps<typeof title> {
40+
ref?: React.Ref<HTMLHeadingElement>;
41+
}
4142

42-
const Title = React.forwardRef<HTMLHeadingElement, TitleProps>(
43-
({className, size, children, ...props}, ref) => (
44-
<h3 ref={ref} className={cn(title({className, size}))} {...props}>
45-
{children}
46-
</h3>
47-
)
43+
const Title = ({className, size, children, ref, ...props}: TitleProps) => (
44+
<h3 ref={ref} className={cn(title({className, size}))} {...props}>
45+
{children}
46+
</h3>
4847
);
49-
Title.displayName = 'Card.Title';
5048

5149
export const Card = Object.assign(CardRoot, {
5250
Title,

frontend/src/components/Pill.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ const pill = cva(
5050

5151
interface PillProps
5252
extends React.HTMLAttributes<HTMLSpanElement>,
53-
VariantProps<typeof pill> {}
53+
VariantProps<typeof pill> {
54+
ref?: React.Ref<HTMLSpanElement>;
55+
}
5456

55-
const Pill = React.forwardRef<HTMLSpanElement, PillProps>(
56-
({className, variant, ...props}, ref) => (
57-
<span ref={ref} className={cn(pill({variant, className}))} {...props} />
58-
)
57+
const Pill = ({className, variant, ref, ...props}: PillProps) => (
58+
<span ref={ref} className={cn(pill({variant, className}))} {...props} />
5959
);
60-
Pill.displayName = 'Pill';
6160

6261
export {Pill, type PillProps};

frontend/src/components/Spinner.tsx

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {cn} from 'utils/cn';
33

44
interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
55
size?: 'sm' | 'md' | 'lg';
6+
ref?: React.Ref<HTMLDivElement>;
67
}
78

89
const sizeClasses = {
@@ -11,24 +12,21 @@ const sizeClasses = {
1112
lg: 'h-12 w-12 border-4',
1213
};
1314

14-
export const Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(
15-
({size = 'md', className, ...props}, ref) => {
16-
return (
17-
<div
18-
ref={ref}
19-
className={cn(
20-
'animate-spin rounded-full border-border-secondary border-t-transparent',
21-
sizeClasses[size],
22-
className
23-
)}
24-
role="status"
25-
aria-label="Loading"
26-
data-testid="spinner"
27-
{...props}
28-
>
29-
<span className="sr-only">Loading...</span>
30-
</div>
31-
);
32-
}
33-
);
34-
Spinner.displayName = 'Spinner';
15+
export const Spinner = ({size = 'md', className, ref, ...props}: SpinnerProps) => {
16+
return (
17+
<div
18+
ref={ref}
19+
className={cn(
20+
'animate-spin rounded-full border-border-secondary border-t-transparent',
21+
sizeClasses[size],
22+
className
23+
)}
24+
role="status"
25+
aria-label="Loading"
26+
data-testid="spinner"
27+
{...props}
28+
>
29+
<span className="sr-only">Loading...</span>
30+
</div>
31+
);
32+
};

frontend/src/routes/$incidentId/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {useEffect} from 'react';
12
import {useSuspenseQuery} from '@tanstack/react-query';
23
import {createFileRoute} from '@tanstack/react-router';
34
import {Card} from 'components/Card';
@@ -20,6 +21,13 @@ function Incident() {
2021
const params = Route.useParams();
2122
const {data: incident} = useSuspenseQuery(incidentDetailQueryOptions(params));
2223

24+
useEffect(() => {
25+
document.title = `${params.incidentId} • Firetower`;
26+
return () => {
27+
document.title = 'Firetower';
28+
};
29+
}, [params.incidentId]);
30+
2331
return (
2432
<div className="space-y-4 p-2">
2533
<IncidentSummary incident={incident} />

0 commit comments

Comments
 (0)