Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: dark-mode #577

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
25779bb
feat!: dark mode
ldeluigi Nov 14, 2024
d38d3de
style: fix more dark mode issues
ldeluigi Nov 15, 2024
917036c
style: complete dark mode implementation
ldeluigi Nov 15, 2024
6186e86
chore: remove hardcoded references to scryfall SVGs
ldeluigi Nov 16, 2024
44ecce2
feat: dark mode switch
ldeluigi Nov 16, 2024
e776569
k8s: maxUnavailable should be less than minReplicas
cyounkins Nov 14, 2024
076a772
chore: bump eslint from 9.14.0 to 9.15.0 (#578)
dependabot[bot] Nov 18, 2024
8260885
chore: bump @typescript-eslint/eslint-plugin from 8.14.0 to 8.15.0 (#…
dependabot[bot] Nov 18, 2024
6a5a0d1
chore: bump markdown-to-jsx from 7.5.0 to 7.6.2 (#581)
dependabot[bot] Nov 18, 2024
1b136b4
chore: bump @types/node from 22.9.0 to 22.10.1 (#585)
dependabot[bot] Dec 6, 2024
445931f
chore: bump @spacecowmedia/spellbook-client from 3.14.2 to 3.14.6 (#586)
dependabot[bot] Dec 6, 2024
e0bcdce
chore: bump react-select from 5.8.2 to 5.9.0 (#590)
dependabot[bot] Dec 20, 2024
0c7f23a
chore: bump @eslint/compat from 1.2.2 to 1.2.4 (#588)
dependabot[bot] Dec 20, 2024
b14d7c1
chore: bump postcss from 8.4.48 to 8.4.49 (#582)
dependabot[bot] Dec 20, 2024
13cdc9e
fix: conditionally show number of cards and results based on parsed d…
ldeluigi Jan 6, 2025
77a16be
chore: bump sass from 1.80.6 to 1.83.1 (#600)
dependabot[bot] Jan 7, 2025
b9e2afb
chore: bump @typescript-eslint/parser from 8.14.0 to 8.19.1 (#601)
dependabot[bot] Jan 7, 2025
85e1619
chore: bump markdown-to-jsx from 7.6.2 to 7.7.2 (#593)
dependabot[bot] Jan 7, 2025
d48f27c
chore: bump @commitlint/config-conventional from 19.5.0 to 19.6.0 (#583)
dependabot[bot] Jan 7, 2025
71982b2
feat: document is:hulkline tag, close #599
ldeluigi Jan 7, 2025
332c403
test: add generated image test
ldeluigi Jan 7, 2025
167c151
fix: error handling in find my combos, closes #596
ldeluigi Jan 7, 2025
a565586
fix: condition for justify-center, closes #594
ldeluigi Jan 7, 2025
8a3594e
feat: add sitemap for every combo, closes #587
ldeluigi Jan 7, 2025
85fb172
fix: multiline card name indentation, fix #456
ldeluigi Jan 7, 2025
32980a9
feat: handle templates in embed.js, closes #482
ldeluigi Jan 7, 2025
3e345af
chore: fix eslint issue
ldeluigi Jan 7, 2025
b97f26d
Merge branch 'main' into feat/dark-mode
ldeluigi Jan 11, 2025
249e007
feat: replace react-cookie with cookies-next
ldeluigi Jan 13, 2025
c17ffea
Merge branch 'main' into feat/dark-mode
ldeluigi Jan 13, 2025
ab9711e
feat: make dark mode dependant from user preference, cookie, local st…
ldeluigi Jan 13, 2025
9589792
fix: issue with nullability of jwt
ldeluigi Jan 13, 2025
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@spacecowmedia/spellbook-client": "^3.14.6",
"canvas": "^2.11.2",
"cookies-next": "^5.0.2",
"debounce": "^2.2.0",
"markdown-to-jsx": "^7.7.2",
"next": "^15.0.3",
"nextjs-progressbar": "^0.0.16",
"pluralize": "^8.0.0",
"react": "^18.3.1",
"react-confirm-alert": "^3.0.6",
"react-cookie": "^7.2.2",
"react-dom": "^18.3.1",
"react-markdown": "^9.0.1",
"react-select": "^5.9.0",
Expand Down Expand Up @@ -72,4 +72,4 @@
"typescript": "^5.6.3",
"wait-on": "^8.0.1"
}
}
}
12 changes: 8 additions & 4 deletions src/assets/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
@tailwind utilities;

html {
@apply bg-white font-body;
@apply bg-white font-body dark:bg-black dark:text-white;
}

body,
Expand All @@ -18,7 +18,7 @@ html,
}

a {
@apply underline text-link;
@apply underline text-link dark:text-primary;
}

#main:focus {
Expand Down Expand Up @@ -57,15 +57,19 @@ a {
}

.heading-title {
@apply font-title text-center text-4xl text-dark uppercase;
@apply font-title text-center text-4xl text-dark uppercase dark:text-light;
}

.heading-subtitle {
@apply text-2xl font-title text-center;
}

.button {
@apply m-4 inline-block py-2 px-3 bg-transparent text-link border-2 border-primary rounded-sm no-underline;
@apply m-4 inline-block py-2 px-3 bg-transparent text-link border-2 border-primary rounded-sm no-underline dark:text-primary;
}

input, textarea, select, option, .input, .inputControl {
@apply border-dark bg-white dark:bg-dark dark:text-light;
}

.button.tight {
Expand Down
21 changes: 13 additions & 8 deletions src/components/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import Link from 'next/link';
import styles from './searchBar.module.scss';
import { NextRouter, useRouter } from 'next/router';
import UserDropdown from '../layout/UserDropdown/UserDropdown';
import { useCookies } from 'react-cookie';
import { apiConfiguration } from 'services/api.service';
import { VariantsApi } from '@spacecowmedia/spellbook-client';
import ThemeSelector from 'components/ui/ThemeSelector/ThemeSelector';
import CookieService from 'services/cookie.service';

type Props = {
onHomepage?: boolean;
Expand Down Expand Up @@ -44,7 +45,6 @@ const SearchBar: React.FC<Props> = ({ onHomepage, className }) => {

const [mobileMenuIsOpen, setMobileMenuIsOpen] = useState(false);
const [inputValue, setInputValue] = useState(getQueryFromRouter(router));
const [cookies, setCookies] = useCookies(['variantCount']);
const [variantCount, setVariantCount] = useState<number>(initialCount);
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
Expand Down Expand Up @@ -73,14 +73,16 @@ const SearchBar: React.FC<Props> = ({ onHomepage, className }) => {
}, [router.query.q]);

useEffect(() => {
if (cookies.variantCount) {
setVariantCount(cookies.variantCount);
handleCountUp(cookies.variantCount);
} else if (!cookies.variantCount) {
const variantCountCookie = CookieService.get('variantCount');
const variantCount = variantCountCookie ? parseInt(variantCountCookie) : undefined;
if (variantCount) {
setVariantCount(variantCount);
handleCountUp(variantCount);
} else if (!variantCount) {
variantsApi
.variantsList({ limit: 1, q: 'legal:commander' })
.then((response) => {
setCookies('variantCount', response.count, { path: '/', maxAge: 3 * 60 * 60 });
CookieService.set('variantCount', response.count, 'hours');
setVariantCount(response.count);
handleCountUp(response.count);
})
Expand Down Expand Up @@ -119,7 +121,7 @@ const SearchBar: React.FC<Props> = ({ onHomepage, className }) => {
</div>

{!onHomepage && (
<div className="flex flex-shrink flex-row items-center desktop-menu">
<div className="flex flex-row-reverse md:flex-row items-center desktop-menu">
<button
id="search-bar-menu-button"
type="button"
Expand All @@ -130,6 +132,9 @@ const SearchBar: React.FC<Props> = ({ onHomepage, className }) => {
<div className="sr-only">Menu</div>
</button>

<span className={`text-white mr-2`}>
<ThemeSelector />
</span>
<Link href="/advanced-search/" className={`hidden md:flex ${styles.menuLink}`}>
<div className={`${styles.advancedSearchIcon} ${styles.linkIcon}`} aria-hidden="true" />
Advanced
Expand Down
3 changes: 1 addition & 2 deletions src/components/SearchBar/searchBar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
}
}


.buttonContainer {
@apply items-center flex-row px-4 text-white md:border-l border-white
@apply items-center flex-row text-white md:border-l border-white
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ const MAX_NUMBER_OF_MATCHING_RESULTS = 20;
const AUTOCOMPLETE_DELAY = 150;
const BLUR_CLOSE_DELAY = 900;

export type AutoCompleteOption = { value: string; label: string; alias?: RegExp; normalizedValue?: string };
export type AutoCompleteOption = {
value: string;
label: string;
alias?: RegExp;
normalizedValue?: string;
normalizedLabel?: string;
};

type Props = {
value: string;
Expand All @@ -25,7 +31,6 @@ type Props = {
inputId: string;
placeholder?: string;
label?: string;
matchAgainstOptionLabel?: boolean;
hasError?: boolean;
useValueForInput?: boolean;
onChange?: (_value: string) => void;
Expand All @@ -41,7 +46,6 @@ const AutocompleteInput: React.FC<Props> = ({
templateAutocomplete,
inputId,
label,
matchAgainstOptionLabel,
useValueForInput,
placeholder,
hasError,
Expand All @@ -66,10 +70,6 @@ const AutocompleteInput: React.FC<Props> = ({
templateAutocomplete;
const inMemory = !active || (!cardAutocomplete && !resultAutocomplete && !templateAutocomplete);

autocompleteOptions?.forEach(
(option) => (option.normalizedValue = option.normalizedValue ?? normalizeStringInput(option.value)),
);

const total = matchingAutoCompleteOptions.length;
const option = matchingAutoCompleteOptions[arrowCounter];
let screenReaderSelectionText = '';
Expand Down Expand Up @@ -226,25 +226,28 @@ const AutocompleteInput: React.FC<Props> = ({
setLoading(false);
}
}
options
.filter((o) => o.normalizedValue === undefined)
.forEach((o) => (o.normalizedValue = o.normalizedValue ?? normalizeStringInput(o.value)));
options
.filter((o) => o.normalizedLabel === undefined)
.forEach((o) => (o.normalizedLabel = o.normalizedLabel ?? normalizeStringInput(o.label)));
return options.filter((option) => {
const mainMatch = option.normalizedValue?.includes(normalizedValue);

if (mainMatch) {
return true;
}

if (matchAgainstOptionLabel) {
const labelMatch = normalizeStringInput(option.label).includes(normalizedValue);
const labelMatch = option.normalizedLabel?.includes(normalizedValue);

if (labelMatch) {
return true;
}
if (labelMatch) {
return true;
}

if (option.alias) {
return normalizedValue.match(option.alias);
}

return false;
});
};
Expand Down Expand Up @@ -291,7 +294,8 @@ const AutocompleteInput: React.FC<Props> = ({
}
setMatchingAutoCompleteOptions([]);
const totalOptions = await findAllMatches(value);
setMatchingAutoCompleteOptions(findBestMatches(totalOptions, value));
const matchingOptions = findBestMatches(totalOptions, value);
setMatchingAutoCompleteOptions(matchingOptions);
};

const handleKeydown = (e: React.KeyboardEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -358,7 +362,7 @@ const AutocompleteInput: React.FC<Props> = ({
{matchingAutoCompleteOptions.map((item, index) => (
<li
key={index}
className={`${styles.autocompleteResult} ${index === arrowCounter && styles.isActive}`}
className={`${inputClassName} ${styles.autocompleteResult} ${index === arrowCounter && styles.isActive}`}
onClick={() => handleClick(item)}
onMouseOver={() => handleAutocompleteItemHover(index)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

.autocompleteResults {
@apply p-0 m-0 bg-white border border-light overflow-auto max-h-48 absolute w-full z-10;
@apply p-0 m-0 bg-white border border-light overflow-auto max-h-48 absolute w-full z-10 dark:bg-dark;
}

.autocompleteResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ const MultiSearchInput: React.FC<Props> = ({
value: option.operator + '|' + (option.numeric ?? '') + '|' + (option.negate ?? ''),
label: option.label,
}))}
selectTextClassName="sm:w-1/2 flex-grow"
selectTextClassName="sm:w-1/2 flex-grow bg-transparent"
selectBackgroundClassName={`${
input.error ? 'border-danger' : 'border-dark'
} border border-b-0 sm:border-b sm:border-r-0 sm:w-1/2 flex-grow`}
Expand All @@ -129,7 +129,7 @@ const MultiSearchInput: React.FC<Props> = ({
value={input.value}
onChange={(value) => handleInputChange(index, value)}
label={inputLabel}
inputClassName="border-dark"
inputClassName={styles.autocompleteInput}
autocompleteOptions={autocompleteOptions}
cardAutocomplete={cardAutocomplete}
resultAutocomplete={resultAutocomplete}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const RadioSearchInput: React.FC<Props> = ({ checkedValue, options, formName, la
value={option.value}
onChange={() => handleChange(option.value)}
/>
<span className="ml-2 text-dark">{option.label}</span>
<span className="ml-2">{option.label}</span>
</label>
))}
</fieldset>
Expand Down
6 changes: 3 additions & 3 deletions src/components/combo/ComboSidebarLinks/ComboSidebarLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ShareComboButtons from './ShareComboButtons/ShareComboButtons';
import Embed from 'components/combo/ComboSidebarLinks/Embed/Embed';
import React from 'react';
import { Variant } from '@spacecowmedia/spellbook-client';
import { useCookies } from 'react-cookie';
import CookieService from 'services/cookie.service';

type Props = {
cards: string[];
Expand All @@ -26,7 +26,7 @@ const ComboSidebarLinks: React.FC<Props> = ({
cardKingdomPrice,
combo,
}) => {
const [cookies, _setCookies] = useCookies(['csbIsStaff']);
const csbIsStaff = CookieService.get<string>('csbIsStaff') === 'true';
return (
<div className="mt-4 mb-4 w-full rounded overflow-hidden">
<BuyComboButtons cards={cards} tcgPlayerPrice={tcgPlayerPrice} cardKingdomPrice={cardKingdomPrice} />
Expand All @@ -36,7 +36,7 @@ const ComboSidebarLinks: React.FC<Props> = ({
Report an Error with this Combo
</Link>
<Embed combo={combo} />
{cookies.csbIsStaff && (
{csbIsStaff && (
<Link
id="edit-combo-button"
className="button w-full"
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const Footer: React.FC<Props> = ({ className, noMargin }) => {
</p>
<p className="my-4">
Commander Spellbook utilizes icons provided by&nbsp;
<a href="https://fontawesome.com/">Font Awesome</a>&nbsp; according to the&nbsp;
<a href="https://fontawesome.com/">Font Awesome</a> according to the&nbsp;
<a href="https://fontawesome.com/license">Font Awesome License</a>.
</p>
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/components/layout/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import {
faClone,
faCheck,
faXmark,
faSun,
faMoon,
faCircleHalfStroke,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classNames from 'classnames';
Expand Down Expand Up @@ -82,6 +85,9 @@ const SPELLBOOK_FA_ICONS = {
copy: faClone,
check: faCheck,
cross: faXmark,
sun: faSun,
moon: faMoon,
halfStrokeCircle: faCircleHalfStroke,
};

export type SpellbookIcon = keyof typeof SPELLBOOK_ICONS | keyof typeof SPELLBOOK_FA_ICONS;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.link {
@apply text-dark no-underline;
@apply text-dark no-underline dark:text-light;
.searchSnippet {
@apply border-2 border-dark pb-2 mb-4 rounded-sm;
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/StyledSelect/StyledSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const StyledSelect: React.FC<Props> = ({
value,
options,
selectBackgroundClassName = 'border border-dark',
selectTextClassName = 'text-dark',
selectTextClassName = styles.selectOption,
onChange,
disabled,
}) => {
Expand Down Expand Up @@ -48,7 +48,7 @@ const StyledSelect: React.FC<Props> = ({
className={`${styles.operatorSelector} ${selectTextClassName} focus:shadow-outline`}
>
{options.map((option, index) => (
<option key={`${label}-input-${index}-${option.label}`} value={option.value} className="text-dark">
<option key={`${label}-input-${index}-${option.label}`} value={option.value} className={styles.selectOption}>
{option.label}
</option>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.operatorSelector {
@apply w-full h-10 pl-3 pr-6 appearance-none bg-transparent;
@apply w-full h-10 pl-3 pr-6 appearance-none;
}
14 changes: 9 additions & 5 deletions src/components/layout/UserDropdown/UserDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import styles from './userDropdown.module.scss';
import React, { useEffect, useState } from 'react';
import { useCookies } from 'react-cookie';
import CookieService from '../../../services/cookie.service';
import Link from 'next/link';

const UserDropdown: React.FC = () => {
const [cookies, _setCookies] = useCookies(['csbUsername', 'csbIsStaff']);
const [username, setUsername] = useState('');
const [csbIsStaff, setCsbIsStaff] = useState(false);

useEffect(() => {
if (cookies.csbUsername) {
setUsername(cookies.csbUsername);
const csbUsername = CookieService.get('csbUsername');
if (csbUsername) {
setUsername(csbUsername);
}
const isStaff = CookieService.get('csbIsStaff') === 'true';
if (isStaff) {
setCsbIsStaff(true);
}
}, []);

Expand All @@ -34,7 +38,7 @@ const UserDropdown: React.FC = () => {
Submit Combo
</button>
</Link>
{cookies.csbIsStaff && (
{csbIsStaff && (
<Link onClick={() => console.log('hello')} href={`${process.env.NEXT_PUBLIC_EDITOR_BACKEND_URL}/admin/`}>
<button type="button" className={styles.dropdownItem}>
Admin Page
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.userDropdownButton {
@apply flex flex-row items-center px-2 rounded bg-indigo-600 text-white;
@apply flex flex-row items-center px-2 rounded bg-indigo-600 text-white ml-2 mr-2;
}

.discordIcon {
Expand Down
Loading