Skip to content

Commit

Permalink
feat(user): hw manage profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
kiremitrov123 committed Mar 6, 2023
1 parent 3a3c7d2 commit 03f0936
Show file tree
Hide file tree
Showing 28 changed files with 924 additions and 15 deletions.
5 changes: 5 additions & 0 deletions src/components/Button/Button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ $large-button-height: 40px;
background-color: var(--highlight-color, theme.$btn-primary-bg);
}

&.delete {
color: variables.$white;
background-color: var(--highlight-color, variables.$red);
}

&.outlined {
border: 1px solid rgba(255, 255, 255, 0.3);

Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styles from './Button.module.scss';

import Spinner from '#components/Spinner/Spinner';

type Color = 'default' | 'primary';
type Color = 'default' | 'primary' | 'delete';

type Variant = 'contained' | 'outlined' | 'text';

Expand Down
5 changes: 5 additions & 0 deletions src/components/FormFeedback/FormFeedback.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
border-radius: 4px;
}

.info {
color: variables.$white;
background-color: theme.$body-bg-color;
}

.error {
color: theme.$form-feedback-error-color;
background-color: theme.$form-feedback-error-bg-color;
Expand Down
3 changes: 2 additions & 1 deletion src/components/FormFeedback/FormFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import styles from './FormFeedback.module.scss';

type Props = {
children?: React.ReactNode;
variant: 'success' | 'warning' | 'error';
variant: 'info' | 'success' | 'warning' | 'error';
};

const FormFeedback: React.FC<Props> = ({ children, variant = 'error' }: Props) => {
const className = classNames(styles.formFeedback, {
[styles.error]: variant === 'error',
[styles.warning]: variant === 'warning',
[styles.success]: variant === 'success',
[styles.info]: variant === 'info',
});
return <div className={className}>{children}</div>;
};
Expand Down
7 changes: 7 additions & 0 deletions src/components/Header/Header.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@
text-align: center;
}
}
.profile {
display:flex;
align-items: center;
h2 {
cursor: pointer;
}
}
//
// mediaQueries
// --------------------------------
Expand Down
27 changes: 17 additions & 10 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import UserMenu from '#components/UserMenu/UserMenu';
import { getPublicUrl } from '#src/utils/domHelpers';
import useBreakpoint, { Breakpoint } from '#src/hooks/useBreakpoint';
import IconButton from '#components/IconButton/IconButton';
import { useAccountStore } from '#src/stores/AccountStore';
import { useConfigStore } from '#src/stores/ConfigStore';

type TypeHeader = 'static' | 'fixed';

Expand Down Expand Up @@ -57,6 +59,8 @@ const Header: React.FC<Props> = ({
showPaymentsMenuItem,
}) => {
const { t } = useTranslation('menu');
const { accessModel } = useConfigStore();
const { canManageProfiles, profile } = useAccountStore();
const [logoLoaded, setLogoLoaded] = useState(false);
const breakpoint = useBreakpoint();
const headerClassName = classNames(styles.header, styles[headerType], {
Expand Down Expand Up @@ -103,16 +107,19 @@ const Header: React.FC<Props> = ({

return isLoggedIn ? (
<React.Fragment>
<IconButton
className={classNames(styles.iconButton, styles.userMenuButton)}
aria-label={t('open_user_menu')}
onClick={() => toggleUserMenu(!userMenuOpen)}
>
<AccountCircle />
</IconButton>
<Popover isOpen={userMenuOpen} onClose={() => toggleUserMenu(false)}>
<UserMenu onClick={() => toggleUserMenu(false)} showPaymentsItem={showPaymentsMenuItem} inPopover />
</Popover>
<div className={styles.profile}>
<IconButton
className={classNames(styles.iconButton, styles.userMenuButton)}
aria-label={t('open_user_menu')}
onClick={() => toggleUserMenu(!userMenuOpen)}
>
<AccountCircle />
</IconButton>
<Popover isOpen={userMenuOpen} onClose={() => toggleUserMenu(false)}>
<UserMenu onClick={() => toggleUserMenu(false)} showPaymentsItem={showPaymentsMenuItem} inPopover />
</Popover>
{canManageProfiles && accessModel === 'SVOD' && <h2 onClick={() => toggleUserMenu(!userMenuOpen)}>Hi, {profile}</h2>}
</div>
</React.Fragment>
) : (
<div className={styles.buttonContainer}>
Expand Down
25 changes: 25 additions & 0 deletions src/components/ProfileBox/AddNewProfile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

import styles from './ProfileBox.module.scss';

type Props = {
onClick: () => void;
};

const AddNewProfile = ({ onClick }: Props) => {
return (
<div onClick={onClick} className={styles.wrapper}>
<div className={`${styles.box} ${styles.circle}`}>
<svg width="36.67" height="36.67" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M33.6667 15.3333H22.6667V4.33329C22.6667 3.36083 22.2804 2.4282 21.5928 1.74057C20.9052 1.05293 19.9725 0.666626 19.0001 0.666626C18.0276 0.666626 17.095 1.05293 16.4074 1.74057C15.7197 2.4282 15.3334 3.36083 15.3334 4.33329V15.3333H4.33341C3.36095 15.3333 2.42832 15.7196 1.74069 16.4072C1.05306 17.0949 0.666748 18.0275 0.666748 19C0.666748 19.9724 1.05306 20.9051 1.74069 21.5927C2.42832 22.2803 3.36095 22.6666 4.33341 22.6666H15.3334V33.6666C15.3334 34.6391 15.7197 35.5717 16.4074 36.2593C17.095 36.947 18.0276 37.3333 19.0001 37.3333C19.9725 37.3333 20.9052 36.947 21.5928 36.2593C22.2804 35.5717 22.6667 34.6391 22.6667 33.6666V22.6666H33.6667C34.6392 22.6666 35.5718 22.2803 36.2595 21.5927C36.9471 20.9051 37.3334 19.9724 37.3334 19C37.3334 18.0275 36.9471 17.0949 36.2595 16.4072C35.5718 15.7196 34.6392 15.3333 33.6667 15.3333Z"
fill="#F7F8FA"
/>
</svg>
</div>
<h2 className={styles.title}>Add new</h2>
</div>
);
};

export default AddNewProfile;
83 changes: 83 additions & 0 deletions src/components/ProfileBox/ProfileBox.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
@use 'src/styles/variables';

.inner {
position: relative;
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 4px;
&:hover {
border: 1px solid variables.$white;
opacity: 0.8;
}
}
.wrapper {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 10px;
cursor: pointer;

.image {
width: 100%;
height: 100%;
}

.box {
position: relative;
width: 140px;
height: 140px;
padding: 10px;
img {
position: relative;
transition: all 0.5s ease;
}
.kids {
position: absolute;
top: 5px;
right: 5px;
color: variables.$link;
}
&:hover {
img {
transform: translate(-5px, -5px);
}
}
}
.circle {
display: flex;
justify-content: center;
align-items: center;
// border: 1px solid rgba(255, 255, 255, 0.3);
background: #1F232C;
border: 1px solid transparent;
border-radius: 100px;
}
.overlay {
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 95%);
border: 1px solid transparent;
border-radius: 4px;
}

&:hover {
.box {
border: 1px solid variables.$white;
opacity: 0.8;
}
h2 {
opacity: 0.8;
}
}



}

35 changes: 35 additions & 0 deletions src/components/ProfileBox/ProfileBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

import styles from './ProfileBox.module.scss';

import Edit from '#src/icons/Edit';

type Props = {
name: string;
image: string;
adult?: boolean;
editMode?: boolean;
onClick: () => void;
onEdit: () => void;
};

const ProfileBox = ({ name, image, adult = true, editMode = false, onClick, onEdit }: Props) => {
return (
<div className={styles.wrapper}>
<div className={styles.inner}>
<div onClick={onClick} className={styles.box}>
<img className={styles.image} src={image} alt="" />
{!adult && <span className={styles.kids}>Kids</span>}
</div>
{editMode && (
<div onClick={onEdit} className={styles.overlay}>
<Edit />
</div>
)}
</div>
<h2 className={styles.title}>{name}</h2>
</div>
);
};

export default ProfileBox;
10 changes: 10 additions & 0 deletions src/components/UserMenu/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import BalanceWallet from '#src/icons/BalanceWallet';
import Exit from '#src/icons/Exit';
import MenuButton from '#components/MenuButton/MenuButton';
import { logout } from '#src/stores/AccountController';
import { useConfigStore } from '#src/stores/ConfigStore';
import { useAccountStore } from '#src/stores/AccountStore';
import ArrowLeftRight from '#src/icons/ArrowLeftRight';

type Props = {
inPopover?: boolean;
Expand All @@ -21,6 +24,8 @@ type Props = {
const UserMenu = ({ showPaymentsItem, inPopover = false, onClick }: Props) => {
const { t } = useTranslation('user');
const navigate = useNavigate();
const { accessModel } = useConfigStore();
const { canManageProfiles } = useAccountStore();

const onLogout = useCallback(async () => {
if (onClick) {
Expand All @@ -36,6 +41,11 @@ const UserMenu = ({ showPaymentsItem, inPopover = false, onClick }: Props) => {
<li>
<MenuButton small={inPopover} onClick={onClick} to="/u/my-account" label={t('nav.account')} startIcon={<AccountCircle />} />
</li>
{accessModel === 'SVOD' && canManageProfiles && (
<li>
<MenuButton small={inPopover} onClick={onClick} to="/u/profiles" label="Switch profile" startIcon={<ArrowLeftRight />} />
</li>
)}
<li>
<MenuButton small={inPopover} onClick={onClick} to="/u/favorites" label={t('nav.favorites')} startIcon={<Favorite />} />
</li>
Expand Down
19 changes: 18 additions & 1 deletion src/containers/AppRoutes/AppRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Route, Routes } from 'react-router-dom';
import { Navigate, Route, Routes } from 'react-router-dom';
import shallow from 'zustand/shallow';

import ErrorPage from '#components/ErrorPage/ErrorPage';
import RootErrorPage from '#components/RootErrorPage/RootErrorPage';
Expand All @@ -12,12 +13,28 @@ import User from '#src/pages/User/User';
import MediaScreenRouter from '#src/pages/ScreenRouting/MediaScreenRouter';
import PlaylistScreenRouter from '#src/pages/ScreenRouting/PlaylistScreenRouter';
import Layout from '#src/containers/Layout/Layout';
import Profiles from '#src/containers/Profiles/Profiles';
import CreateProfile from '#src/containers/Profiles/CreateProfile';
import { useConfigStore } from '#src/stores/ConfigStore';
import { useAccountStore } from '#src/stores/AccountStore';
import EditProfile from '#src/containers/Profiles/EditProfile';
import useQueryParam from '#src/hooks/useQueryParam';

export default function AppRoutes() {
const { t } = useTranslation('error');
const userModal = useQueryParam('u');

const { accessModel } = useConfigStore(({ config, accessModel }) => ({ config, accessModel }), shallow);
const { canManageProfiles, profile } = useAccountStore(({ canManageProfiles, profile }) => ({ canManageProfiles, profile }), shallow);
const shouldManageProfiles = canManageProfiles && !profile && (accessModel === 'SVOD' || accessModel === 'AUTHVOD') && !userModal;

return (
<Routes>
<Route index={shouldManageProfiles} element={<Navigate to="/u/profiles" />} />
<Route path="/u/profiles" element={<Profiles />} />
<Route path="/u/profiles/create" element={<CreateProfile />} />
<Route path="/u/profiles/edit" element={<Profiles editMode />} />
<Route path="/u/profiles/edit/:id" element={<EditProfile />} />
<Route element={<Layout />} errorElement={<RootErrorPage />}>
<Route index element={<Home />} />
<Route path="/p/:id" element={<PlaylistScreenRouter />} />
Expand Down
Loading

0 comments on commit 03f0936

Please sign in to comment.