Skip to content

Commit

Permalink
Merge pull request #453 from commons-stack/style/dark-mode
Browse files Browse the repository at this point in the history
Dark mode feature
  • Loading branch information
kristoferlund authored Jun 15, 2022
2 parents 287be99 + cb2effc commit 28a57b2
Show file tree
Hide file tree
Showing 34 changed files with 177 additions and 63 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Dark mode! #420 #453
- Support multiple wallets: WalletConnect, Trust, Rainbow etc #424
- Export the user list as csv #402 #450
- Option to turn on/off the Discord role requirement for Praise givers #419 #434 #440
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/account/EthAccountDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const EthAccountDialog = ({
<div className="flex items-center justify-center min-h-screen">
<Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-30" />
<div
className="relative max-w-xl p-6 mx-auto bg-white rounded"
className="relative max-w-xl p-6 mx-auto bg-white rounded dark:bg-slate-900"
ref={contentRef}
>
<div className="flex justify-end">
Expand All @@ -61,7 +61,7 @@ const EthAccountDialog = ({
<div className="flex justify-center mb-8">
<Jazzicon address={address} className="w-12 h-12" />
</div>
<Dialog.Title className="text-center">
<Dialog.Title className="text-center dark:text-white">
{shortenEthAddress(address)}
</Dialog.Title>
<div className="flex justify-center space-x-4">
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/praise/Praise.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const Praise = ({
)}
arrow
>
<span className="ml-2 text-xs text-gray-500">
<span className="ml-2 text-xs text-gray-500 dark:text-white/50">
{localizeAndFormatIsoDateRelative(praise.createdAt)}
</span>
</Tooltip>
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/praise/PraiseRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const PraiseRow = ({ praise, children }: PraiseRowProps): JSX.Element => {

return (
<div
className="cursor-pointer hover:bg-gray-100"
className="cursor-pointer px-5 hover:bg-gray-100 dark:hover:bg-slate-500"
onClick={handleClick(praise)}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/settings/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const DisabledFormFields = (
<Notice type="danger" className="mb-8">
<span>Settings locked for this period</span>
</Notice>
<div className="mb-2 space-y-4">
<div className="mb-2 space-y-4 px-5">
{settings.map((setting: SettingDto | PeriodSettingDto) => (
<div key={setting.key}>
<label className="block font-bold">{setting.label}</label>
Expand Down
30 changes: 26 additions & 4 deletions packages/frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Toaster } from 'react-hot-toast';
import { BrowserRouter as Router } from 'react-router-dom';
import { RecoilRoot } from 'recoil';
import { RecoilRoot, useRecoilValue } from 'recoil';
import RecoilNexus from 'recoil-nexus';
import { useErrorBoundary } from 'use-error-boundary';
// eslint-disable-next-line import/no-unresolved
Expand All @@ -13,14 +13,16 @@ import {
wallet,
RainbowKitProvider,
lightTheme,
Theme,
Theme as RainbowTheme,
darkTheme,
} from '@rainbow-me/rainbowkit';
import { merge } from 'lodash';
import { configureChains, createClient, WagmiConfig, chain } from 'wagmi';
import { publicProvider } from 'wagmi/providers/public';
import Routes from './navigation/Routes';
import ErrorPage from './pages/ErrorPage';
import LoadScreen from '@/components/LoadScreen';
import { Theme } from '@/model/theme';
import './styles/globals.css';

const LOAD_DELAY = 500;
Expand Down Expand Up @@ -92,7 +94,7 @@ const customRainbowkitTheme = merge(lightTheme(), {
connectButton: '0.25rem', // tailwind radius 'rounded'
modal: '0.25rem',
},
} as Theme);
} as RainbowTheme);

interface DelayedLoadingProps {
children: JSX.Element;
Expand All @@ -101,13 +103,25 @@ const DelayedLoading = ({
children,
}: DelayedLoadingProps): JSX.Element | null => {
const [delay, setDelay] = React.useState<boolean>(true);
const theme = useRecoilValue(Theme);

React.useEffect(() => {
setTimeout(() => {
setDelay(false);
}, LOAD_DELAY);
}, []);

React.useEffect(() => {
const root = document.documentElement;
if (theme !== 'Light') {
root.classList.add('dark');
localStorage.setItem('theme', 'Dark');
} else {
localStorage.setItem('theme', 'Light');
root.classList.remove('dark');
}
}, [theme]);

// Possibility to add loader here
if (delay) return null;
return children;
Expand All @@ -127,12 +141,20 @@ const ErrorBoundary = ({ children }: ErrorBoundaryProps): JSX.Element => {
);
};

const getRainbowTheme = (): RainbowTheme => {
const currentMode = localStorage.getItem('theme');
if (currentMode === 'Dark') {
return darkTheme();
}
return customRainbowkitTheme;
};

ReactDOM.render(
<React.StrictMode>
<RecoilRoot>
<RecoilNexus />
<WagmiConfig client={wagmiClient}>
<RainbowKitProvider chains={chains} theme={customRainbowkitTheme}>
<RainbowKitProvider chains={chains} theme={getRainbowTheme()}>
<Router>
<main>
<DelayedLoading>
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/layouts/AuthenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const AuthenticatedLayout = (): JSX.Element | null => {
</div>

<div className="md:pl-64 flex flex-col flex-1">
<div className="sticky top-0 z-10 md:hidden py-1 px-1 bg-gray-50 border-b shadow-sm flex justify-start items-center w-full">
<div className="sticky top-0 z-10 md:hidden py-1 px-1 bg-gray-50 dark:bg-slate-900 border-b shadow-sm flex justify-start items-center w-full">
<button
type="button"
className="-ml-0.5 -mt-0.5 h-12 w-12 inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/layouts/SignMessageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const SignMessageLayout = ({
<div className="w-full p-5 text-2xl font-bold">
<FontAwesomeIcon icon={faPrayingHands} size="1x" className="m-2" />
</div>
<div className="p-4 py-8 m-auto space-y-8 border border-solid rounded-lg shadow-sm bg-gray-50 w-96">
<div className="p-4 py-8 m-auto space-y-8 border border-solid rounded-lg shadow-sm bg-gray-50 w-96 dark:bg-slate-900">
{children}

{isLoading && !data && !message ? (
Expand Down
6 changes: 6 additions & 0 deletions packages/frontend/src/model/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { atom } from 'recoil';

export const Theme = atom<string>({
key: 'Theme',
default: localStorage.getItem('theme') || 'Light',
});
50 changes: 48 additions & 2 deletions packages/frontend/src/navigation/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,33 @@ import {
faQuestionCircle,
faUserFriends,
faBook,
faMoon,
faSun,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Menu } from '@headlessui/react';
import { Link } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { useRecoilValue, useRecoilState } from 'recoil';
import { Theme } from '@/model/theme';
import NavItem from './NavItem';
import { classNames } from '../utils';

export default function Nav(): JSX.Element {
const [theme, setTheme] = useRecoilState(Theme);
const logoSetting = useRecoilValue(SingleSetting('LOGO'));

const handleTheme = (theme: string): void => {
if (theme === 'Dark') {
setTheme('Dark');
localStorage.setItem('theme', 'Dark');
} else {
setTheme('Light');
localStorage.setItem('theme', 'Light');
}
};

return (
<nav className="flex h-screen border-r shadow-sm md:w-64 md:flex-col md:fixed bg-gray-50">
<nav className="flex h-screen border-r shadow-sm md:w-64 md:flex-col md:fixed bg-gray-50 dark:bg-slate-900 dark:text-white">
<div className="flex flex-col justify-between h-full">
<div className="w-full">
<ul className="relative h-full p-0 m-0 list-none">
Expand Down Expand Up @@ -61,6 +77,36 @@ export default function Nav(): JSX.Element {
<NavItem icon={faQuestionCircle} description="FAQ" to="/faq" />
</ul>
</div>
<div className="h-12 m-4 mt-auto flex">
{/* <div>{theme} mode</div>
<Switch
checked={theme === 'Dark'}
onChange={handleTheme}
icon={<FontAwesomeIcon icon={faSun} size="lg" />}
checkedIcon={<FontAwesomeIcon icon={faMoon} size="lg" />}
/> */}
<div
className={classNames(
theme === 'Light' ? 'bg-blue-100/50 text-blue-500' : '',
'cursor-pointer grow rounded-l-lg border-2 border-r flex items-center justify-center gap-4'
)}
onClick={(): void => handleTheme('Light')}
>
<FontAwesomeIcon icon={faSun} size="lg" />
Light
</div>
<div
className={classNames(
theme === 'Dark' ? 'bg-blue-800/20' : '',
'cursor-pointer grow rounded-r-lg border-2 border-l flex items-center justify-center gap-4'
)}
onClick={(): void => handleTheme('Dark')}
>
Dark
<FontAwesomeIcon icon={faMoon} size="lg" />
</div>
</div>

<div className="w-full border-t">
<Menu as="div" className="flex flex-col justify-center">
<Menu.Button className="flex items-center justify-between w-full selection:hover:text-gray-500 focus:outline-none">
Expand Down
6 changes: 4 additions & 2 deletions packages/frontend/src/navigation/NavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ const NavItem = ({ icon, description, to }: NavProps): JSX.Element => {
<NavLink
to={to}
className={(isActive): string =>
`relative px-4 py-1 cursor-pointer no-underline flex items-center text-black ${
isActive ? ' bg-gray-200' : ' hover:bg-gray-100'
`relative px-4 py-1 cursor-pointer no-underline flex items-center ${
isActive
? ' bg-gray-200 dark:bg-slate-700'
: ' hover:bg-gray-100 dark:hover:bg-slate-800'
}`
}
id={to.substring(1) + '-nav-button'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ const EventLogsTable = (): JSX.Element | null => {
if (data.docs.length === 0) return null;

return (
<div className="praise-box">
<div className="w-full space-y-4">
<div className="praise-box px-0">
<div className="w-full">
{data.docs.map((eventlog, i) => (
<EventLog
eventlog={eventlog}
className={`${i % 2 === 0 && 'bg-gray-100'} px-2`}
className={`${i % 2 === 0 && 'bg-gray-100 dark:bg-slate-500'} px-7`}
key={i}
/>
))}
Expand All @@ -37,7 +37,7 @@ const EventLogsTable = (): JSX.Element | null => {
<FontAwesomeIcon
icon={faArrowLeft}
size="1x"
className="mr-2"
className="mr-2 pl-5"
/>
Previous
</a>
Expand All @@ -54,7 +54,7 @@ const EventLogsTable = (): JSX.Element | null => {
<FontAwesomeIcon
icon={faArrowRight}
size="1x"
className="ml-2"
className="ml-2 pr-5"
/>
</a>
)}
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/pages/MyPraise/MyPraisePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const MyPraise = (): JSX.Element => {

<ActiveNoticesBoard />

<div className="praise-box">
<div className="praise-box px-0">
<React.Suspense fallback="Loading…">
<MyPraiseTable />
</React.Suspense>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ const PeriodsForm = (): JSX.Element => {
</Field>
<Field name="endDate">
{({ input }): JSX.Element => (
<div className="mb-5">
<div className="mb-5 w-72">
<label className="block">End date (UTC)</label>
<DayInput
name={input.name}
value={input.value}
onChange={input.onChange}
className="w-72 block"
inputClassName="w-100"
className="block w-72"
inputClassName="w-full"
/>
{apiResponse && (
<FieldErrorMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ const PeriodDetailPage = (): JSX.Element | null => {
<QuantifierMessage />
</React.Suspense>

<div className="flex sm:space-x-4 sm:flex-row flex-col">
<div className="flex flex-col sm:space-x-4 sm:flex-row">
<div>
<div className="w-full sm:w-40 py-5 mb-5 break-words border rounded-lg shadow-sm bg-gray-50">
<div className="w-40 py-5 mb-5 break-words border rounded-lg shadow-sm bg-gray-50 dark:bg-slate-600">
<nav>
<NavItem
to={`${url}/receivers`}
Expand All @@ -107,7 +107,7 @@ const PeriodDetailPage = (): JSX.Element | null => {
</div>
</div>

<div className="praise-box w-full">
<div className="w-full praise-box px-0">
<Suspense fallback="Loading…">
<Switch>
<Route path={`${path}/receivers`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const PeriodAssignDialog = ({
return (
<div className="flex items-center justify-center min-h-screen">
<Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-30" />
<div className="relative max-w-xl pb-16 mx-auto bg-white rounded">
<div className="relative max-w-xl pb-16 mx-auto bg-white rounded dark:bg-slate-600 dark:text-white">
<div className="flex justify-end p-6">
<button className="praise-button-round" onClick={onClose}>
<FontAwesomeIcon icon={faTimes} size="1x" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const PeriodCloseDialog = ({
return (
<div className="flex items-center justify-center min-h-screen">
<Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-30" />
<div className="relative max-w-xl pb-16 mx-auto bg-white rounded">
<div className="relative max-w-xl pb-16 mx-auto bg-white rounded dark:bg-slate-600 dark:text-white">
<div className="flex justify-end p-6">
<button className="praise-button-round" onClick={onClose}>
<FontAwesomeIcon icon={faTimes} size="1x" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const PeriodDateForm = (): JSX.Element | null => {
input.onChange(e);
void handleSubmit(e);
}}
inputClassName="relative py-0 px-1 pl-1 my-0 text-sm bg-transparent border border-transparent hover:border-gray-300 w-24"
inputClassName="relative py-0 px-1 pl-1 my-0 text-sm bg-transparent border border-transparent dark:border-transparent hover:border-gray-300 w-24 dark:hover:border-slate-800 dark:bg-transparent"
tzLabel="UTC"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const PeriodNameForm = (): JSX.Element | null => {
autoComplete="off"
ref={inputRef}
placeholder="e.g. May-June"
className="relative left-[-5px] pl-1 text-xl font-semibold bg-transparent border border-transparent hover:border-gray-300"
className="relative left-[-5px] pl-1 text-xl font-semibold bg-transparent border border-transparent dark:border-transparent hover:border-gray-300 dark:hover:border-slate-800 dark:bg-transparent"
onKeyDown={(e): void => {
switch (e.key) {
case 'Tab':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const ReceiverTable = (): JSX.Element | null => {
return (
// eslint-disable-next-line react/jsx-key
<tr
className="cursor-pointer hover:bg-gray-100"
className="cursor-pointer hover:bg-gray-100 dark:hover:bg-slate-500"
{...row.getRowProps()}
onClick={handleClick(row.original)}
>
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/pages/Periods/PeriodsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const PeriodsPage = (): JSX.Element => {

<ActiveNoticesBoard />

<div className="praise-box">
<div className="praise-box px-0">
<AdminOnly>
<div className="mb-2 text-right">
<div className="mb-2 text-right px-7">
<Link to="/periods/createupdate">
<button className="praise-button" id="create-period-button">
<FontAwesomeIcon icon={faPlus} size="1x" className="mr-2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const PeriodReceiverTable = (): JSX.Element | null => {

if (!praiseList) return null;
return (
<div className="praise-box">
<div className="praise-box px-0">
{praiseList?.map((praise) => (
<PraiseRow praise={praise} key={praise?._id}>
<Praise praise={praise} showReceiver={false} />
Expand Down
Loading

0 comments on commit 28a57b2

Please sign in to comment.