96 lines
3.6 KiB
TypeScript
96 lines
3.6 KiB
TypeScript
'use client';
|
|
import { FunctionComponent, useState } from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
import { Box, Collapse, Stack, Typography } from '@mui/material';
|
|
import AppIcon from '@/components/common/AppIcon';
|
|
import AppButton from '@/components/common/AppButton';
|
|
import EscrowNotice from '@/components/EscrowNotice';
|
|
|
|
interface ExplainerStep {
|
|
icon: string;
|
|
labelKey: string;
|
|
}
|
|
|
|
const STEPS: ExplainerStep[] = [
|
|
{ icon: 'payment', labelKey: 'escrow_step_pay' },
|
|
{ icon: 'lock', labelKey: 'escrow_step_hold' },
|
|
{ icon: 'verified', labelKey: 'escrow_step_release' },
|
|
];
|
|
|
|
/**
|
|
* Wraps the product-mandated `EscrowNotice` (never edited) with an optional «چطور کار میکند؟» expander: a
|
|
* 3-step visual (پرداخت ← امانت نزد بالینیار ← آزادسازی پس از تایید پایان ویزیت) grounded in
|
|
* `product/payments/escrow-ledger.md`, plus the cancellation/refund implication. Used from checkout and the
|
|
* confirmation receipt so escrow — the platform's whole reason to pay on-platform — gets more than one
|
|
* alert line at the moment of maximum skepticism.
|
|
* @component EscrowExplainer
|
|
*/
|
|
const EscrowExplainer: FunctionComponent = () => {
|
|
const t = useTranslations('payment');
|
|
const [open, setOpen] = useState(false);
|
|
|
|
return (
|
|
<Stack sx={{ gap: 1 }}>
|
|
<EscrowNotice />
|
|
<AppButton
|
|
variant="text"
|
|
color="primary"
|
|
size="small"
|
|
onClick={() => setOpen((v) => !v)}
|
|
aria-expanded={open}
|
|
endIcon={
|
|
<Box
|
|
component="span"
|
|
sx={{ display: 'inline-flex', transition: 'transform 150ms ease', transform: open ? 'rotate(180deg)' : 'none' }}
|
|
>
|
|
<AppIcon icon="expand" size={18} />
|
|
</Box>
|
|
}
|
|
sx={{ alignSelf: 'flex-start', px: 0.5 }}
|
|
>
|
|
{t('escrow_explainer_toggle')}
|
|
</AppButton>
|
|
<Collapse in={open}>
|
|
<Stack sx={{ gap: 1.5, p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
|
|
<Stack
|
|
direction="row"
|
|
sx={{ gap: { xs: 1.5, sm: 2 }, alignItems: 'flex-start', flexWrap: 'wrap', justifyContent: 'space-between' }}
|
|
>
|
|
{STEPS.map((step, index) => (
|
|
<Stack key={step.labelKey} direction="row" sx={{ gap: 1, alignItems: 'center', flex: '1 1 auto' }}>
|
|
<Stack sx={{ gap: 0.5, alignItems: 'center', minWidth: 72 }}>
|
|
<Stack
|
|
sx={{
|
|
width: 40,
|
|
height: 40,
|
|
borderRadius: '50%',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
bgcolor: 'var(--bal-primary-soft)',
|
|
}}
|
|
>
|
|
<AppIcon icon={step.icon} size={20} color="var(--bal-primary)" />
|
|
</Stack>
|
|
<Typography variant="caption" sx={{ fontWeight: 700, textAlign: 'center' }}>
|
|
{t(step.labelKey)}
|
|
</Typography>
|
|
</Stack>
|
|
{index < STEPS.length - 1 ? (
|
|
<Box sx={{ flex: 'none', display: { xs: 'none', sm: 'block' }, pt: 2 }}>
|
|
<AppIcon icon="forward" size={16} color="var(--bal-text-secondary)" />
|
|
</Box>
|
|
) : null}
|
|
</Stack>
|
|
))}
|
|
</Stack>
|
|
<Typography variant="caption" sx={{ color: 'text.secondary' }}>
|
|
{t('escrow_cancellation_note')}
|
|
</Typography>
|
|
</Stack>
|
|
</Collapse>
|
|
</Stack>
|
|
);
|
|
};
|
|
|
|
export default EscrowExplainer;
|