Skip to content

Commit

Permalink
Nathan/UI changes (#324)
Browse files Browse the repository at this point in the history
### Summary

Resolves #313

- Moved github button according to design on Figma
- Added donation button
- Added donation banner component which is shown only once ever
- Replaced action button in information modal with donation button as
per design

### How to Test

Run website and observe the new donate now button in the information
modal, and the donate banner across the top. The new banner closes when
you press the 'X', the GitHub button is in the bottom now, and the
donate button is in the top navbar.

---------

Co-authored-by: Yatharth Bhargava <[email protected]>
  • Loading branch information
Nathan-Papa and yatharth-b authored Apr 1, 2024
1 parent b00b78c commit fc0af9f
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 69 deletions.
Binary file added public/donate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/App/content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ErrorBoundary from '../ErrorBoundary';
import HeaderDisplay from '../HeaderDisplay';
import Map from '../Map';
import Finals from '../Finals';
import DonateBanner from '../DonateBanner';
import {
AppNavigationContext,
AppMobileNav,
Expand Down Expand Up @@ -39,6 +40,7 @@ function AppContentBase(): React.ReactElement {
tabs={NAV_TABS}
captureRef={captureRef}
/>
<DonateBanner />
<ErrorBoundary
// ErrorBoundary.fallback is a normal render prop, not a component.
// eslint-disable-next-line react/no-unstable-nested-components
Expand Down
13 changes: 13 additions & 0 deletions src/components/Attribution/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from 'react';
import { faGithub } from '@fortawesome/free-brands-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import { Button } from '..';
import { classes } from '../../utils/misc';
import { DESKTOP_BREAKPOINT } from '../../constants';
import useScreenWidth from '../../hooks/useScreenWidth';
Expand All @@ -10,6 +13,15 @@ export default function Attribution(): React.ReactElement {
const mobile = !useScreenWidth(DESKTOP_BREAKPOINT);
return (
<div className={classes('Attribution')}>
{!mobile ? (
<Button href="https://github.com/gt-scheduler/website">
<FontAwesomeIcon fixedWidth icon={faGithub} size="2xl" />
<span className="githubText">GitHub</span>
</Button>
) : (
<div />
)}

<p>
Copyright (c) 2023 with{' '}
<span role="img" aria-label="love">
Expand All @@ -22,6 +34,7 @@ export default function Attribution(): React.ReactElement {
</a>
.
</p>
<p>&nbsp;</p>
</div>
);
}
6 changes: 5 additions & 1 deletion src/components/Attribution/stylesheet.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
justify-content: space-between;
text-align: center;
color: inherit;
border-top: 1px solid $color-border;
Expand All @@ -20,4 +20,8 @@
flex-wrap: wrap;
justify-content: center;
}

.githubText {
margin-left: 5px;
}
}
53 changes: 53 additions & 0 deletions src/components/DonateBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import useLocalStorageState from 'use-local-storage-state';
import { faX } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import Button from '../Button';
import { DESKTOP_BREAKPOINT } from '../../constants';
import useScreenWidth from '../../hooks/useScreenWidth';

import './stylesheet.scss';

const BANNER_LOCAL_STORAGE_KEY = '2024-04-01-spr2024-donate-banner';

export default function DonateBanner(): React.ReactElement {
const [hasSeen, setHasSeen] = useLocalStorageState(BANNER_LOCAL_STORAGE_KEY, {
defaultValue: false,
storageSync: true,
});
const mobile = !useScreenWidth(DESKTOP_BREAKPOINT);

return (
<div>
{!hasSeen ? (
<div className="banner">
<div className="spacer" />
<span>
{!mobile
? 'Help keep GT Scheduler and its amazing features running!'
: 'Help us and'}
<Button
className="donateButton"
href="https://donorbox.org/gt-scheduler"
>
<b className="buttonText">
{!mobile ? 'Donate today.' : 'donate today.'}
</b>
</Button>
</span>
<Button
className="close-button"
onClick={(): void => {
setHasSeen(true);
}}
>
<FontAwesomeIcon fixedWidth icon={faX} size="lg" />
</Button>
</div>
) : (
<div />
)}
</div>
);
}
23 changes: 23 additions & 0 deletions src/components/DonateBanner/stylesheet.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.banner {
width: 100%;
height: fit-content;
color: white;
background-color: #C56E5B;
font-family: "Roboto", sans-serif;
display: flex;
justify-content: space-between;
align-items: center;

.donateButton {
display: inline-block;
padding: 10px 6px;
}

.donateButton:hover {
text-decoration: underline;
}

.spacer {
width: 49px;
}
}
74 changes: 16 additions & 58 deletions src/components/HeaderActionBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import { faGithub } from '@fortawesome/free-brands-svg-icons';
import {
faDownload,
faCalendarAlt,
faPaste,
faCaretDown,
faShare,
faCircle,
faHandHoldingDollar,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { useCallback, useContext, useState } from 'react';
import useLocalStorageState from 'use-local-storage-state';
import React, { useCallback, useState } from 'react';

import { Button, InvitationModal } from '..';
import {
LARGE_MOBILE_BREAKPOINT,
LARGE_DESKTOP_BREAKPOINT,
DESKTOP_BREAKPOINT,
} from '../../constants';
import useMedia from '../../hooks/useMedia';
import { AccountContext, AccountContextValue } from '../../contexts/account';
import { AccountContextValue } from '../../contexts/account';
import { classes } from '../../utils/misc';
import { DropdownMenu, DropdownMenuAction } from '../Select';
import AccountDropdown from '../AccountDropdown';
import ShareIcon from '../ShareIcon';
import useScreenWidth from '../../hooks/useScreenWidth';

import './stylesheet.scss';

Expand All @@ -39,9 +34,6 @@ export type HeaderActionBarProps = {
enableDownloadCalendar?: boolean;
};

// Key to mark when a user has already seen the invite modal.
const MODAL_LOCAL_STORAGE_KEY = '2023-05-10-spr2023-invite-modal';

/**
* Displays the icon buttons (with optional text)
* that appear at the top of the app in the header,
Expand All @@ -60,25 +52,8 @@ export default function HeaderActionBar({
onDownloadCalendar = (): void => undefined,
enableDownloadCalendar = false,
}: HeaderActionBarProps): React.ReactElement {
const { type } = useContext(AccountContext);

const [invitationOpen, setInvitationOpen] = useState(false);
const [seenInviteModal, setSeenInviteModal] = useLocalStorageState<boolean>(
MODAL_LOCAL_STORAGE_KEY,
{
defaultValue: false,
storageSync: true,
}
);

const mobile = !useScreenWidth(DESKTOP_BREAKPOINT);

const openInvitation = useCallback(() => {
setInvitationOpen(true);
if (!seenInviteModal) {
setSeenInviteModal(true);
}
}, [seenInviteModal, setSeenInviteModal]);
const hideInvitation = useCallback(() => setInvitationOpen(false), []);

// Coalesce the export options into the props for a single <DropdownMenu>
Expand Down Expand Up @@ -121,6 +96,19 @@ export default function HeaderActionBar({

return (
<div className={classes('header-action-bar', className)} style={style}>
<Button
href="https://donorbox.org/gt-scheduler"
className="header-action-bar__button"
>
<FontAwesomeIcon
className="header-action-bar__button-icon"
fixedWidth
icon={faHandHoldingDollar}
/>

<div className="header-action-bar__button-text">Donate</div>
</Button>

<DropdownMenu
disabled={!enableExport}
items={exportActions}
Expand All @@ -135,36 +123,6 @@ export default function HeaderActionBar({
</DropdownMenu>
<InvitationModal show={invitationOpen} onHide={hideInvitation} />

{!mobile && (
<Button
onClick={openInvitation}
disabled={type === 'signedOut'}
className={classes('header-action-bar__button', 'invite-button')}
>
<FontAwesomeIcon
className="header-action-bar__button-icon"
fixedWidth
icon={faShare}
/>
<div className="header-action-bar__button-text">Invite</div>
{seenInviteModal || type === 'signedOut' ? null : (
<FontAwesomeIcon className="circle" fixedWidth icon={faCircle} />
)}
</Button>
)}

<Button
href="https://github.com/gt-scheduler/website"
className="header-action-bar__button"
>
<FontAwesomeIcon
className="header-action-bar__button-icon"
fixedWidth
icon={faGithub}
/>
<div className="header-action-bar__button-text">GitHub</div>
</Button>

<AccountDropdown state={accountState} />
</div>
);
Expand Down
41 changes: 32 additions & 9 deletions src/components/InformationModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React, { useEffect, useState } from 'react';
import useLocalStorageState from 'use-local-storage-state';
import { faX } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import { classes } from '../../utils/misc';
import { DESKTOP_BREAKPOINT } from '../../constants';
import Modal from '../Modal';
import useScreenWidth from '../../hooks/useScreenWidth';
import Button from '../Button';

import './stylesheet.scss';

Expand All @@ -23,9 +26,19 @@ const OUTDATED_LOCAL_STORAGE_KEY = [
* Additionally, make sure to change `MODAL_LOCAL_STORAGE_KEY`
* with another unique value that has never been used before.
*/
export function InformationModalContent(): React.ReactElement {

export type InformationModalContentProps = {
setShow: (show: boolean) => void;
};

export function InformationModalContent({
setShow,
}: InformationModalContentProps): React.ReactElement {
return (
<>
<Button className="close-button" onClick={(): void => setShow(false)}>
<FontAwesomeIcon fixedWidth icon={faX} size="xl" />
</Button>
<img
style={{
width: '150px',
Expand All @@ -45,19 +58,21 @@ export function InformationModalContent(): React.ReactElement {
>
New Feature: Compare Schedules
</h1>
<h4 style={{ opacity: 0.7, fontWeight: 700 }}>March 10, 2024</h4>
<h4 style={{ opacity: 0.7, fontWeight: 700 }}>April 2, 2024</h4>
<div className="information-content">
<p>
Hello <span style={{ color: '#EDA91F' }}>Yellow Jackets!</span> We are
excited to announce a new feature for GT Scheduler.
<br />
<br />
Use Compare Schedules to share and compare your schedules with your
friends!
Share your schedule with other students and they can share theirs
back. Then toggle &quot;Compare Schedules&quot; and click on the other
students&apos; schedules to compare.
<br />
<br />
Add your friends&apos; schedules to yours and view them using the
panel on the right side of the page below your profile icon.
However, to keep GT Scheduler and its amazing features, we need to
maintain our costs. Please consider donating to help keep GT Scheduler
running!
</p>
<div className="information-images">
<img
Expand Down Expand Up @@ -106,10 +121,18 @@ export default function InformationModal(): React.ReactElement {
className={classes('InformationModal', mobile && 'mobile')}
show={show}
onHide={(): void => setShow(false)}
buttons={[{ label: 'Got it!', onClick: (): void => setShow(false) }]}
width={800}
buttons={[
{
label: 'Donate Today',
onClick: (): void => {
setShow(false);
window.open('https://donorbox.org/gt-scheduler');
},
},
]}
width={850}
>
<InformationModalContent />
<InformationModalContent setShow={setShow} />
</Modal>
);
}
6 changes: 5 additions & 1 deletion src/components/InformationModal/stylesheet.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
.InformationModal {
.close-button {
width: fit-content;
margin-left: auto;
}
.information-content {
display: flex;
position: relative;
Expand All @@ -8,7 +12,7 @@
margin-bottom: 20px;
p {
margin: 0px;
width: 12vw;
width: 15vw;
}
.information-images {
display: flex;
Expand Down

0 comments on commit fc0af9f

Please sign in to comment.