import styled from '@emotion/native'; import { ViewProps as ViewPropsBase } from 'react-native'; import { variant } from 'styled-system'; import { ColorName, ViewStyle } from '@emotion/react'; import { Container, Row, Col } from 'components/layout'; import { CheckMark, CloseThick } from 'icons'; import { Text } from 'components/text'; import { Fab, FabColorVariant } from 'components/fab'; import { IconColorVariantsType } from 'icons/types'; import { capitalize } from 'utils/text'; import { MotiView } from 'moti'; import { useReactiveVar } from '@apollo/client'; import { AlertOptionsVar, alertOptionsVar } from 'state-management/alert'; import { Visible } from 'components/visible'; import { metrics } from 'config'; import { useResponsiveLayout, useTheme } from 'hooks'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { FC, useCallback, useEffect, useRef, useState } from 'react'; const { Z_INDEX, STYLES, DURATION } = metrics; const variants: Record = { success: { borderColor: 'success', backgroundColor: 'success-02', }, 'success-dark': { borderColor: 'success', backgroundColor: 'success-08', }, info: { borderColor: 'grey-02', backgroundColor: 'base-01', }, 'info-dark': { borderColor: 'grey-02', backgroundColor: 'base-01', }, warning: { borderColor: 'primary', backgroundColor: 'primary-02', }, 'warning-dark': { borderColor: 'primary', backgroundColor: 'primary-08', }, error: { borderColor: 'secondary', backgroundColor: 'secondary-02', }, 'error-dark': { borderColor: 'secondary', backgroundColor: 'secondary-08', }, }; const iconVariants: Record = { success: 'success', info: 'body', warning: 'primary', error: 'secondary', }; export const LocalAlert = styled(Container)( variant({ variants, }), variant({ prop: 'shapeVariant', variants: { default: { p: 'xs', borderRadius: 'button', borderWidth: 1, }, }, }) ); LocalAlert.defaultProps = { shapeVariant: 'default', }; export const AlertWrapper: FC = ({ alertVariantLocal, leftElementVar, iconColorVariant, contentVar, messageVar, variantVar, textColor, titleVar, closeAlert, }) => { const { activeThemeMode } = useTheme(); const closeColor = activeThemeMode === 'dark' ? 'white' : 'body'; return ( {leftElementVar || } {contentVar || ( <> {capitalize(variantVar || titleVar)} {messageVar} )} } /> ); }; export const Alert: React.FC = ({}) => { const [remainingTime, setRemainingTime] = useState(DURATION.alertStayTime); const { marginTopVar, messageVar, contentVar, leftElementVar, isOpenVar, variantVar, }: AlertOptionsVar = useReactiveVar(alertOptionsVar); const { isMobile, isTablet } = useResponsiveLayout(); const { top } = useSafeAreaInsets(); const { activeThemeMode } = useTheme(); const timerRef = useRef(null); const iconColorVariant = activeThemeMode === 'dark' ? 'white' : iconVariants[variantVar]; const textColor = activeThemeMode === 'dark' ? 'white' : 'body'; const marginTop = Number(marginTopVar) > 0 ? marginTopVar : top + STYLES.topBarHeight; const marginTopBefore = Number(marginTop) + 100; const tabletLeftRight = isTablet ? '25%' : '30%'; const leftRight = isMobile ? 10 : tabletLeftRight; const alertVariantLocal = activeThemeMode === 'dark' ? (`${variantVar}-dark` as AlertDarkVariant) : variantVar; const resetTimer = useCallback(() => { setRemainingTime(DURATION.alertStayTime); }, []); const startTimer = useCallback(() => { timerRef.current = setInterval(() => { setRemainingTime((time) => time - 1); }, 1000); return () => { clearInterval(timerRef.current); resetTimer(); }; }, [resetTimer]); const closeAlert = useCallback(() => { resetTimer(); alertOptionsVar({ isOpenVar: false, variantVar: 'info' }); clearInterval(timerRef.current); }, [resetTimer]); useEffect(() => { if (remainingTime <= 0) { resetTimer(); alertOptionsVar({ isOpenVar: false, variantVar: 'info' }); clearInterval(timerRef.current); } }, [remainingTime, resetTimer]); useEffect(() => { if (isOpenVar) { startTimer(); } }, [isOpenVar, startTimer]); return ( ); }; export type AlertVariant = AlertLightVariant | AlertDarkVariant; export type AlertLightVariant = 'success' | 'info' | 'warning' | 'error'; export type AlertDarkVariant = 'success-dark' | 'info-dark' | 'warning-dark' | 'error-dark'; export interface LocalAlertProps extends ViewPropsBase { variant?: AlertVariant; shapeVariant?: 'default'; body?: string | number; } export interface AlertWrapperProps { alertVariantLocal: AlertVariant; leftElementVar?: JSX.Element; contentVar?: JSX.Element; titleVar?: string; messageVar?: string; variantVar: AlertLightVariant; iconColorVariant: ColorName; textColor: ColorName; closeAlert: () => void; }