Skip to content

Commit 99c85a9

Browse files
committed
added darkmode everywhere
1 parent 2291bab commit 99c85a9

File tree

41 files changed

+415
-230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+415
-230
lines changed

dev-dist/sw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ define(['./workbox-5357ef54'], function (workbox) {
8181
[
8282
{
8383
url: 'index.html',
84-
revision: '0.m4cfs2nec8',
84+
revision: '0.mtq2duqj29g',
8585
},
8686
],
8787
{},

src/components/ActivityRow/ActivityRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function ActivityRow({ activity, stage, timeZone, showRoom = true }: Acti
3131
<Link
3232
key={activity.id}
3333
className={classNames(
34-
'flex flex-col w-full p-2 even:bg-slate-50 hover:bg-slate-100 even:hover:bg-slate-200',
34+
'flex flex-col w-full p-2 text-gray-900 dark:text-white even:bg-slate-50 even:dark:bg-gray-800 hover:bg-slate-100 dark:hover:bg-gray-700 even:hover:bg-slate-200 even:dark:hover:bg-gray-600',
3535
{
3636
'opacity-50': isOver,
3737
},
Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AssignmentCode } from '@wca/helpers';
22
import { useTranslation } from 'react-i18next';
3-
import { Pill } from '../Pill';
3+
import { BaseAssignmentPill } from '../Pill';
44

55
interface AssignmentLabelProps {
66
assignmentCode: AssignmentCode;
@@ -11,11 +11,11 @@ export function AssignmentLabel({ assignmentCode }: AssignmentLabelProps) {
1111

1212
if (assignmentCode.match(/judge/i)) {
1313
return (
14-
<Pill className="bg-blue-200">
14+
<BaseAssignmentPill className="bg-blue-200 dark:bg-blue-900">
1515
{t('common.assignments.staff-judge.noun', {
1616
defaultValue: assignmentCode.replace('staff-', ''),
1717
})}
18-
</Pill>
18+
</BaseAssignmentPill>
1919
);
2020
}
2121

@@ -25,24 +25,46 @@ export function AssignmentLabel({ assignmentCode }: AssignmentLabelProps) {
2525

2626
switch (assignmentCode) {
2727
case 'competitor':
28-
return <Pill className="bg-green-200">{name}</Pill>;
28+
return (
29+
<BaseAssignmentPill className="bg-green-200 dark:bg-green-900">{name}</BaseAssignmentPill>
30+
);
2931
case 'staff-scrambler':
30-
return <Pill className="bg-yellow-200">{name}</Pill>;
32+
return (
33+
<BaseAssignmentPill className="bg-yellow-200 dark:bg-yellow-900">{name}</BaseAssignmentPill>
34+
);
3135
case 'staff-runner':
32-
return <Pill className="bg-orange-200">{name}</Pill>;
36+
return (
37+
<BaseAssignmentPill className="bg-orange-200 dark:bg-orange-900">{name}</BaseAssignmentPill>
38+
);
3339
case 'staff-dataentry':
34-
return <Pill className="bg-cyan-200">{name}</Pill>;
40+
return (
41+
<BaseAssignmentPill className="bg-cyan-200 dark:bg-cyan-900">{name}</BaseAssignmentPill>
42+
);
3543
case 'staff-announcer':
36-
return <Pill className="bg-violet-200">{name}</Pill>;
44+
return (
45+
<BaseAssignmentPill className="bg-violet-200 dark:bg-violet-900">{name}</BaseAssignmentPill>
46+
);
3747
case 'staff-delegate':
38-
return <Pill className="bg-purple-200">{name}</Pill>;
48+
return (
49+
<BaseAssignmentPill className="bg-purple-200 dark:bg-purple-900">{name}</BaseAssignmentPill>
50+
);
3951
case 'staff-stagelead':
40-
return <Pill className="bg-fuchsia-200">{name}</Pill>;
52+
return (
53+
<BaseAssignmentPill className="bg-fuchsia-200 dark:bg-fuchsia-900">
54+
{name}
55+
</BaseAssignmentPill>
56+
);
4157
case 'staff-stream':
42-
return <Pill className="bg-pink-300">{name}</Pill>;
58+
return (
59+
<BaseAssignmentPill className="bg-pink-300 dark:bg-pink-900">{name}</BaseAssignmentPill>
60+
);
4361
case 'staff-photo':
44-
return <Pill className="bg-amber-500">{name}</Pill>;
62+
return (
63+
<BaseAssignmentPill className="bg-amber-500 dark:bg-amber-900">{name}</BaseAssignmentPill>
64+
);
4565
default:
46-
return <Pill className="bg-blue-100">{name}</Pill>;
66+
return (
67+
<BaseAssignmentPill className="bg-blue-100 dark:bg-blue-900">{name}</BaseAssignmentPill>
68+
);
4769
}
4870
}

src/components/Breadcrumbs/Breadcrumbs.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import classNames from 'classnames';
22
import { Fragment } from 'react';
33
import { Link } from 'react-router-dom';
4-
import { Pill, PillProps } from '../Pill';
4+
import { BreadcrumbPill, Pill, PillProps } from '../Pill';
55

66
export type Breadcrumb =
77
| {
@@ -25,14 +25,14 @@ export const Breadcrumbs = ({ breadcrumbs }: BreadcrumbsProps) => {
2525
{index > 0 && <span className="text-gray-500 dark:text-gray-400">·</span>}
2626
{'href' in breadcrumb ? (
2727
<Link to={breadcrumb.href}>
28-
<Pill
28+
<BreadcrumbPill
2929
{...breadcrumb.pillProps}
3030
className={classNames(
3131
'min-h-[40px] hover:ring-2',
3232
breadcrumb.pillProps?.className,
3333
)}>
3434
{label}
35-
</Pill>
35+
</BreadcrumbPill>
3636
</Link>
3737
) : (
3838
<span key={label}>{label}</span>

src/components/Button/Button.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,27 @@ import { ButtonHTMLAttributes, PropsWithChildren } from 'react';
33

44
export interface ButtonProps extends PropsWithChildren<ButtonHTMLAttributes<HTMLButtonElement>> {
55
className?: string;
6+
variant?: 'blue' | 'green' | 'gray' | 'light';
67
}
78

8-
export const Button = ({ className, ...props }: ButtonProps) => {
9-
return <button className={classNames('px-4 py-2 rounded-md text-white', className)} {...props} />;
9+
export const Button = ({ className, variant = 'blue', ...props }: ButtonProps) => {
10+
const variantClasses = {
11+
blue: 'bg-blue-200 hover:bg-blue-300 dark:bg-blue-700 dark:hover:bg-blue-600 text-gray-900 dark:text-white border border-blue-300 dark:border-blue-600',
12+
green:
13+
'bg-green-200 hover:bg-green-400 dark:bg-green-700 dark:hover:bg-green-600 text-gray-900 dark:text-white border border-green-300 dark:border-green-600',
14+
gray: 'bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-900 dark:text-white border border-gray-300 dark:border-gray-600',
15+
light:
16+
'bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-900 dark:text-white border border-gray-300 dark:border-gray-600',
17+
};
18+
19+
return (
20+
<button
21+
className={classNames(
22+
'px-4 py-2 rounded-md transition-colors',
23+
variantClasses[variant],
24+
className,
25+
)}
26+
{...props}
27+
/>
28+
);
1029
};

src/components/CompetitionSelect/CompetitionSelect.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { useCallback, useRef } from 'react';
22
import { useTranslation } from 'react-i18next';
3+
import type { ClassNamesConfig, StylesConfig } from 'react-select';
34
import AsyncSelect from 'react-select/async';
45
import { OptionProps } from 'react-select/dist/declarations/src';
56
import { fetchSearchCompetition } from '@/lib/api';
7+
import { useUserSettings } from '@/providers/UserSettingsProvider';
68
import { CompetitionListItem } from '../CompetitionListItem';
79

810
export interface CompetitionSelectProps {
@@ -12,6 +14,8 @@ export interface CompetitionSelectProps {
1214

1315
export const CompetitionSelect = ({ onSelect, className }: CompetitionSelectProps) => {
1416
const { t } = useTranslation();
17+
const { effectiveTheme } = useUserSettings();
18+
const isDark = effectiveTheme === 'dark';
1519

1620
const loadOptions = useDebounced(async (inputValue: string) => {
1721
try {
@@ -32,16 +36,92 @@ export const CompetitionSelect = ({ onSelect, className }: CompetitionSelectProp
3236
[onSelect],
3337
);
3438

39+
const classNames: ClassNamesConfig<ApiCompetition, false> = {
40+
control: (state) =>
41+
[
42+
// Base sizing and rounded look
43+
'min-h-[38px] rounded-md',
44+
// Backgrounds
45+
'bg-white dark:bg-gray-800',
46+
// Borders + focus
47+
'border border-gray-200 dark:border-gray-700',
48+
state.isFocused
49+
? 'ring-1 ring-blue-500 dark:ring-blue-400 border-blue-500 dark:border-blue-400'
50+
: '',
51+
].join(' '),
52+
valueContainer: () => 'text-gray-900 dark:text-white',
53+
singleValue: () => 'text-gray-900 dark:text-white',
54+
input: () => 'text-gray-900 dark:text-white',
55+
placeholder: () => 'text-gray-600 dark:text-gray-400',
56+
indicatorsContainer: () => 'text-gray-500 dark:text-gray-400',
57+
dropdownIndicator: (state) =>
58+
[
59+
'text-gray-500 dark:text-gray-400',
60+
state.isFocused ? 'text-blue-600 dark:text-blue-400' : '',
61+
].join(' '),
62+
clearIndicator: () =>
63+
'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300',
64+
menu: () => 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-md',
65+
menuList: () => 'bg-white dark:bg-gray-800',
66+
option: (state) =>
67+
[
68+
'text-gray-900 dark:text-white',
69+
state.isFocused ? 'bg-gray-100 dark:bg-gray-700' : '',
70+
state.isSelected ? 'bg-blue-100 dark:bg-blue-900' : '',
71+
].join(' '),
72+
noOptionsMessage: () => 'text-gray-600 dark:text-gray-400',
73+
};
74+
75+
const styles: StylesConfig<ApiCompetition, false> = {
76+
control: (base, state) => ({
77+
...base,
78+
backgroundColor: 'transparent',
79+
borderColor: state.isFocused ? (isDark ? '#60a5fa' : '#3b82f6') : base.borderColor,
80+
boxShadow: state.isFocused ? `0 0 0 1px ${isDark ? '#60a5fa' : '#3b82f6'}` : 'none',
81+
':hover': {
82+
...base[':hover'],
83+
borderColor: state.isFocused ? (isDark ? '#60a5fa' : '#3b82f6') : base.borderColor,
84+
},
85+
}),
86+
menu: (base) => ({
87+
...base,
88+
backgroundColor: 'transparent',
89+
}),
90+
menuList: (base) => ({
91+
...base,
92+
backgroundColor: 'transparent',
93+
}),
94+
option: (base) => ({
95+
...base,
96+
backgroundColor: 'transparent',
97+
}),
98+
input: (base) => ({
99+
...base,
100+
color: isDark ? '#ffffff' : '#111827', // gray-900
101+
}),
102+
singleValue: (base) => ({
103+
...base,
104+
color: isDark ? '#ffffff' : '#111827', // gray-900
105+
}),
106+
placeholder: (base) => ({
107+
...base,
108+
color: isDark ? '#9ca3af' : '#4b5563', // dark: gray-400, light: gray-600
109+
}),
110+
};
111+
35112
return (
36113
<AsyncSelect<ApiCompetition>
37114
className={className}
115+
classNamePrefix="cg-select"
38116
cacheOptions
39117
loadOptions={loadOptions}
40118
placeholder={t('common.competitionSelect.placeholder')}
41119
noOptionsMessage={() => t('common.competitionSelect.noOptions')}
42120
components={{
43121
Option: CompetitionOption,
44122
}}
123+
classNames={classNames}
124+
styles={styles}
45125
onChange={handleSelectOption}
46126
/>
47127
);

src/components/ExternalLink/ExternalLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function ExternalLink({
1515
target="_blank"
1616
rel="noreferrer"
1717
className={classNames(
18-
'flex align-center justify-between w-full bg-blue-200 px-4 py-2 rounded hover:opacity-80',
18+
'flex align-center justify-between w-full bg-blue-200 dark:bg-blue-700 dark:hover:bg-blue-600 px-4 py-2 rounded hover:opacity-80',
1919
className,
2020
)}>
2121
{children}

src/components/LinkButton/LinkButton.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@ import { Link, LinkProps } from 'react-router-dom';
44
export interface LinkButtonProps {
55
to: LinkProps['to'];
66
title: string;
7-
color: 'blue' | 'green';
7+
variant?: 'blue' | 'green' | 'gray' | 'light';
88
className?: string;
99
}
1010

11-
export const LinkButton = ({ to, title, color, className }: LinkButtonProps) => {
11+
export const LinkButton = ({ to, title, variant = 'blue', className }: LinkButtonProps) => {
12+
const variantClasses = {
13+
blue: 'bg-blue-200 hover:bg-blue-300 dark:bg-blue-800 dark:hover:bg-blue-600 text-gray-900 dark:text-white border-blue-300 dark:border-blue-600',
14+
green:
15+
'bg-green-200 hover:bg-green-300 dark:bg-green-700 dark:hover:bg-green-600 text-gray-900 dark:text-white border-green-300 dark:border-green-600',
16+
gray: 'bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-900 dark:text-white border-gray-300 dark:border-gray-600',
17+
light:
18+
'bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-900 dark:text-white border-gray-300 dark:border-gray-600',
19+
};
20+
1221
return (
1322
<Link
1423
to={to}
1524
className={classNames(
1625
'px-4 py-2 shadow-sm rounded-md w-full border p-2 cursor-pointer transition-colors duration-150 min-h-[40px]',
17-
{
18-
'bg-blue-200 hover:bg-blue-300': color === 'blue',
19-
'bg-green-200 hover:bg-green-300': color === 'green',
20-
},
26+
variantClasses[variant],
2127
className,
2228
)}>
2329
{title}

src/components/Notebox/Notebox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export function NoteBox({ text, prefix = 'Note', className }: NoteBoxProps) {
1010
return (
1111
<p
1212
className={classNames(
13-
'bg-yellow-100 p-2 border-b-1 rounded-md text-gray-800 text-xs',
13+
' p-2 rounded-md border-b-1 text-xs bg-yellow-100 dark:bg-yellow-900 text-gray-800 dark:text-white',
1414
className,
1515
)}>
1616
{prefix && <b>{prefix}: </b>}

src/components/Pill/Pill.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,27 @@ export const Pill = ({ className, ...props }: PillProps) => {
1313
/>
1414
);
1515
};
16+
17+
export const BreadcrumbPill = ({ className, ...props }: PillProps) => {
18+
return (
19+
<span
20+
className={classNames(
21+
`inline-flex justify-center items-center px-1.5 py-1 ring-1 ring-inset rounded-md shadow-sm dark:ring-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:shadow-gray-800`,
22+
className,
23+
)}
24+
{...props}
25+
/>
26+
);
27+
};
28+
29+
export const BaseAssignmentPill = ({ className, ...props }: PillProps) => {
30+
return (
31+
<span
32+
className={classNames(
33+
`inline-flex justify-center items-center px-2 py-1 ring-1 ring-inset font-medium rounded-md shadow-sm dark:ring-gray-600 dark:shadow-gray-800`,
34+
className,
35+
)}
36+
{...props}
37+
/>
38+
);
39+
};

0 commit comments

Comments
 (0)