GdprBanner: slideout on accept
This commit is contained in:
parent
4f0e104fc4
commit
f13cfcaf8c
|
@ -1,3 +1,4 @@
|
||||||
|
import classNames from 'classnames';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ const acceptedGdpr = !!localStorage.getItem('soapbox:gdpr');
|
||||||
const GdprBanner: React.FC = () => {
|
const GdprBanner: React.FC = () => {
|
||||||
/** Track whether the banner has already been displayed once. */
|
/** Track whether the banner has already been displayed once. */
|
||||||
const [shown, setShown] = useState<boolean>(acceptedGdpr);
|
const [shown, setShown] = useState<boolean>(acceptedGdpr);
|
||||||
|
const [slideout, setSlideout] = useState(false);
|
||||||
|
|
||||||
const soapbox = useSoapboxConfig();
|
const soapbox = useSoapboxConfig();
|
||||||
const isLoggedIn = useAppSelector(state => !!state.me);
|
const isLoggedIn = useAppSelector(state => !!state.me);
|
||||||
|
@ -17,7 +19,8 @@ const GdprBanner: React.FC = () => {
|
||||||
|
|
||||||
const handleAccept = () => {
|
const handleAccept = () => {
|
||||||
localStorage.setItem('soapbox:gdpr', 'true');
|
localStorage.setItem('soapbox:gdpr', 'true');
|
||||||
setShown(true);
|
setSlideout(true);
|
||||||
|
setTimeout(() => setShown(true), 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
const showBanner = soapbox.gdpr && !isLoggedIn && !shown;
|
const showBanner = soapbox.gdpr && !isLoggedIn && !shown;
|
||||||
|
@ -27,7 +30,7 @@ const GdprBanner: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Banner theme='opaque'>
|
<Banner theme='opaque' className={classNames('transition-transform', { 'translate-y-full': slideout })}>
|
||||||
<Stack space={2}>
|
<Stack space={2}>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text size='xl' weight='bold'>
|
<Text size='xl' weight='bold'>
|
||||||
|
|
|
@ -4,17 +4,18 @@ import React from 'react';
|
||||||
interface IBanner {
|
interface IBanner {
|
||||||
theme: 'frosted' | 'opaque',
|
theme: 'frosted' | 'opaque',
|
||||||
children: React.ReactNode,
|
children: React.ReactNode,
|
||||||
|
className?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Displays a sticky full-width banner at the bottom of the screen. */
|
/** Displays a sticky full-width banner at the bottom of the screen. */
|
||||||
const Banner: React.FC<IBanner> = ({ theme, children }) => {
|
const Banner: React.FC<IBanner> = ({ theme, children, className }) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-testid='banner'
|
data-testid='banner'
|
||||||
className={classNames('fixed bottom-0 left-0 right-0 py-4 z-50', {
|
className={classNames('fixed bottom-0 left-0 right-0 py-4 z-50', {
|
||||||
'backdrop-blur bg-primary-900/80': theme === 'frosted',
|
'backdrop-blur bg-primary-900/80': theme === 'frosted',
|
||||||
'bg-white dark:bg-slate-800 text-black dark:text-white shadow-lg dark:shadow-inset': theme === 'opaque',
|
'bg-white dark:bg-slate-800 text-black dark:text-white shadow-lg dark:shadow-inset': theme === 'opaque',
|
||||||
})}
|
}, className)}
|
||||||
>
|
>
|
||||||
<div className='max-w-3xl md:max-w-7xl mx-auto lg:grid lg:grid-cols-12'>
|
<div className='max-w-3xl md:max-w-7xl mx-auto lg:grid lg:grid-cols-12'>
|
||||||
<div className='col-span-9 col-start-4 xl:col-start-4 xl:col-span-6 md:px-8'>
|
<div className='col-span-9 col-start-4 xl:col-start-4 xl:col-span-6 md:px-8'>
|
||||||
|
|
Loading…
Reference in New Issue