Skip to content

Commit

Permalink
feat: redesign onboarding page (#25)
Browse files Browse the repository at this point in the history
* Add topChildren to TallCard
  • Loading branch information
hobroker authored Apr 13, 2022
1 parent 96e927b commit 18b86ec
Show file tree
Hide file tree
Showing 17 changed files with 271 additions and 209 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@ const UpcomingEpisodesCollection = ({ episodes, loading }: Props) => (
>
{episodes.map((episode) => (
<Box key={episode.externalId}>
<Typography variant="subtitle2" sx={{ textAlign: 'center' }}>
{DateTime.fromISO(episode.airDate).toFormat('ccc, MMM d')}
</Typography>
<TallEpisodeCard episode={episode} />
<TallEpisodeCard
episode={episode}
topChildren={
<Typography
variant="subtitle2"
sx={{ textAlign: 'center', fontWeight: 700 }}
>
{DateTime.fromISO(episode.airDate).toFormat('ccc, MMM d')}
</Typography>
}
/>
</Box>
))}
</TallCardCollection>
Expand Down
7 changes: 1 addition & 6 deletions src/features/onboarding/components/GenresOnboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ const GenresOnboarding = () => {
const canRender = genres.length;

return (
<Stack
direction="row"
flexWrap="wrap"
alignItems="center"
justifyContent="center"
>
<Stack direction="row" flexWrap="wrap" alignItems="center">
{canRender ? (
genres.map(({ name, externalId }) => {
const isSelected = selectedGenres.includes(externalId);
Expand Down
35 changes: 32 additions & 3 deletions src/features/onboarding/components/OnboardingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
import React from 'react';
import type { TypographyProps } from '@mui/material';
import { Box, Typography } from '@mui/material';
import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
import MovieIcon from '@mui/icons-material/Movie';
import { styled } from '@mui/material/styles';
import PageWrapper from '../../../components/PageWrapper';
import VerticalStepper from './VerticalStepper';
import GenresStep from './Steps/GenresStep';
import ShowsStep from './Steps/ShowsStep';

const Title = styled(({ ...props }: TypographyProps) => (
<Typography variant="h5" mb={0.5} {...props} />
))`
display: flex;
align-items: center;
`;

const OnboardingPage = () => (
<PageWrapper>
<VerticalStepper />
<PageWrapper sx={{ mt: 2 }}>
<Box mb={2}>
<Title variant="h4">Let's personalize your profile</Title>
</Box>
<Box mb={2}>
<Title>
<FormatListBulletedIcon color="primary" sx={{ mr: 1 }} />
Select your favorite genres
</Title>
<GenresStep />
</Box>
<Box mb={2}>
<Title>
<MovieIcon color="primary" sx={{ mr: 1 }} />
Add some TV Shows to your profile
</Title>
<ShowsStep />
</Box>
</PageWrapper>
);

Expand Down
11 changes: 1 addition & 10 deletions src/features/onboarding/components/Steps/ShowsStep.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import { Box, Typography } from '@mui/material';
import ShowsOnboarding from '../ShowsOnboarding';
import ShowsOnboardingProvider from '../../contexts/ShowsOnboardingContext';
import PartialWatchlistProvider from '../../../watchlist/contexts/PartialWatchlistContext';

const ShowsStep = () => (
<ShowsOnboardingProvider>
<PartialWatchlistProvider>
<Box>
<Typography variant="body1" mb={2}>
We found some popular items based on your favorite genres.
</Typography>
<ShowsOnboarding />
</Box>
</PartialWatchlistProvider>
<ShowsOnboarding />
</ShowsOnboardingProvider>
);

Expand Down
96 changes: 0 additions & 96 deletions src/features/onboarding/components/VerticalStepper.tsx

This file was deleted.

18 changes: 6 additions & 12 deletions src/features/shows/components/TallShowCard.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { useContext } from 'react';
import { PartialShow, Status } from '../../../generated/graphql';
import { PartialWatchlistContext } from '../../watchlist/contexts/PartialWatchlistContext';
import WatchlistAction from './WatchlistAction';
import useWatchlistActions from '../hooks/useWatchlistActions';
import TallCard from './base/TallCard';
import WatchlistOverlayAction from './WatchlistOverlayAction';

interface Props {
show: PartialShow;
}

const TallShowCard = ({ show }: Props) => {
const { upsertWatchlistItem } = useContext(PartialWatchlistContext);
const { upsertWatchlistItem } = useWatchlistActions();

const onClick = (status: Status) => {
const showId = show.externalId;
Expand All @@ -18,14 +17,9 @@ const TallShowCard = ({ show }: Props) => {
};

return (
<TallCard
tallImage={show.tallImage}
actions={
<>
<WatchlistAction status={show.status} onClick={onClick} />
</>
}
/>
<TallCard tallImage={show.tallImage}>
<WatchlistOverlayAction status={show.status} onClick={onClick} />
</TallCard>
);
};

Expand Down
41 changes: 0 additions & 41 deletions src/features/shows/components/WatchlistAction.tsx

This file was deleted.

66 changes: 66 additions & 0 deletions src/features/shows/components/WatchlistOverlayAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import { alpha, styled } from '@mui/material/styles';
import { Box, Button } from '@mui/material';
import classNames from 'classnames';
import { Status } from '../../../generated/graphql';

interface OverlayProps {
status: Status;
}

const Overlay = styled(Box)`
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100%;
transition: ${({ theme }) => theme.transitions.create('opacity')};
opacity: 0;
background-color: ${({ theme }) => alpha(theme.palette.common.black, 0.5)};
&.status-in-watchlist {
opacity: 1;
}
`;

const StyledActionButton = styled(Button)`
padding: ${({ theme }) => theme.spacing(4)};
transition: ${({ theme }) => theme.transitions.create('opacity')};
width: 100%;
height: 100%;
svg {
font-size: ${({ theme }) => theme.typography.h3.fontSize};
}
`;

interface Props extends OverlayProps {
onClick: (status: Status) => void;
}

const STATUS_TOGGLE_MAP = {
[Status.InWatchlist]: Status.None,
[Status.None]: Status.InWatchlist,
[Status.StoppedWatching]: Status.InWatchlist,
} as const;

const WatchlistOverlayAction = ({ status, onClick }: Props) => {
const handleClick = () => {
onClick(STATUS_TOGGLE_MAP[status]);
};

return (
<Overlay
className={classNames({
'status-in-watchlist': status === Status.InWatchlist,
})}
>
<StyledActionButton onClick={handleClick}>
<CheckCircleOutlineIcon />
</StyledActionButton>
</Overlay>
);
};

export default WatchlistOverlayAction;
3 changes: 3 additions & 0 deletions src/features/shows/components/base/TallCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,18 @@ interface Props {
tallImage?: string | null;
actions?: ReactNode;
onClick?: () => void;
topChildren?: ReactNode;
}

const TallCard = ({
tallImage,
actions,
onClick,
children,
topChildren,
}: PropsWithChildren<Props>) => (
<StyledWrapper variant="elevation" onClick={onClick}>
{topChildren}
<StyledActions>{actions}</StyledActions>
<StyledImage src={makeTallSmallImage(tallImage || '')} />
{children}
Expand Down
Loading

0 comments on commit 18b86ec

Please sign in to comment.