First Commit

This commit is contained in:
cesnimda
2026-03-21 11:55:27 +01:00
commit 2e8a29b4d0
1757 changed files with 166084 additions and 0 deletions
@@ -0,0 +1,122 @@
'use client';
import PropTypes from 'prop-types';
// @mui
import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
// @third-party
import { motion } from 'motion/react';
// @project
import ButtonAnimationWrapper from '@/components/ButtonAnimationWrapper';
import ContainerWrapper from '@/components/ContainerWrapper';
import { GraphicsCard } from '@/components/cards';
import { ProfileGroup } from '@/components/cards/profile-card';
import SvgIcon from '@/components/SvgIcon';
import { SECTION_COMMON_PY } from '@/utils/constant';
// @assets
import Arrow from '@/images/graphics/Arrow';
/*************************** CALL TO ACTION - 4 ***************************/
/**
*
* Demos:
* - [CTA4](https://www.saasable.io/blocks/cta/cta4)
*
* API:
* - [CTA4 API](https://phoenixcoded.gitbook.io/saasable/ui-kit/development/components/cta/cta4#props-details)
*/
export default function Cta4({ headLine, primaryBtn, profileGroups, list, clientContent }) {
const transformValues = { xs: 'rotate(45deg)', sm: 'rotate(320deg)', md: 'unset' };
return (
<ContainerWrapper sx={{ py: SECTION_COMMON_PY }}>
<GraphicsCard>
<Box sx={{ p: { xs: 3, sm: 4, md: 5 } }}>
<Grid container spacing={{ xs: 5, sm: 0, md: 3 }} sx={{ alignItems: 'flex-end' }}>
<Grid size={{ xs: 12, sm: 9, md: 8 }}>
<Stack sx={{ gap: 5 }}>
<ProfileGroup {...profileGroups} />
<Stack sx={{ gap: { xs: 2, sm: 5 } }}>
{typeof headLine === 'string' ? <Typography variant="h2">{headLine}</Typography> : headLine}
{list && (
<Stack direction={{ sm: 'row' }} sx={{ columnGap: { xs: 1, sm: 3 }, rowGap: 1, flexWrap: 'wrap' }}>
{list.map((item, index) => (
<motion.div
key={index}
initial={{ opacity: 0, x: -30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.2, ease: 'easeInOut', delay: index * 0.6 }}
>
<Stack direction="row" sx={{ gap: 1, alignItems: 'center' }}>
<SvgIcon name="tabler-rosette-discount-check" color="text.secondary" stroke={1} />
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
{item.primary}
</Typography>
</Stack>
</motion.div>
))}
</Stack>
)}
</Stack>
</Stack>
</Grid>
<Grid sx={{ position: 'relative', pl: { md: 3 }, pt: { md: 3 } }} size={{ sm: 3, md: 4 }}>
<Box
sx={{
position: 'absolute',
top: { xs: -36, sm: -98, md: -68 },
right: { xs: -70, sm: 40, md: 100 },
transform: transformValues
}}
>
<Arrow />
</Box>
<Typography
variant="subtitle1"
sx={{
color: 'primary.main',
width: 94,
position: 'absolute',
top: { xs: 6, sm: -160, md: -82 },
right: { xs: -160, sm: 0 }
}}
>
{clientContent}
</Typography>
<Box sx={{ textAlign: 'right' }}>
<motion.div
initial={{ scale: 0.9 }}
animate={{ opacity: 1, y: 0, scale: [1, 1.05, 1] }}
transition={{ duration: 1.1, delay: 0.1, ease: 'easeInOut', repeat: Infinity }}
whileHover={{ scale: 1, transition: { duration: 0.3 } }}
whileTap={{ scale: 0.95 }}
>
<ButtonAnimationWrapper>
<Button color="primary" size="large" variant="contained" sx={{ minWidth: { md: 263 } }} {...primaryBtn} />
</ButtonAnimationWrapper>
</motion.div>
</Box>
</Grid>
</Grid>
</Box>
</GraphicsCard>
</ContainerWrapper>
);
}
Cta4.propTypes = {
headLine: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
primaryBtn: PropTypes.any,
profileGroups: PropTypes.object,
list: PropTypes.array,
clientContent: PropTypes.string
};
@@ -0,0 +1,200 @@
'use client';
import PropTypes from 'prop-types';
// @mui
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import OutlinedInput from '@mui/material/OutlinedInput';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
// @third-party
import { motion } from 'motion/react';
// @project
import ButtonAnimationWrapper from '@/components/ButtonAnimationWrapper';
import ContainerWrapper from '@/components/ContainerWrapper';
import { GraphicsCard } from '@/components/cards';
import { ProfileGroup } from '@/components/cards/profile-card';
import LogoWatermark from '@/components/logo/LogoWatermark';
import Typeset from '@/components/Typeset';
import { SECTION_COMMON_PY } from '@/utils/constant';
// @assets
import Wave from '@/images/graphics/Wave';
/*************************** CALL TO ACTION - 5 ***************************/
/**
*
* Demos:
* - [CTA5](https://www.saasable.io/blocks/cta/cta5)
*
* API:
* - [CTA5 API](https://phoenixcoded.gitbook.io/saasable/ui-kit/development/components/cta/cta5#props-details)
*/
export default function Cta5({ heading, caption, label, input = false, primaryBtn, secondaryBtn, description, saleData, profileGroups }) {
return (
<ContainerWrapper sx={{ py: SECTION_COMMON_PY }}>
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{
duration: 0.5,
delay: 0.4
}}
>
<Grid container spacing={1.5}>
<Grid size={{ xs: 12, sm: 8, md: 9 }}>
<motion.div initial={{ opacity: 0, y: -100 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, delay: 0.6 }}>
<GraphicsCard sx={{ position: 'relative' }}>
<Stack
sx={{ alignItems: 'flex-start', gap: { xs: 5.75, sm: 10 }, p: { xs: 3, sm: 4, md: 8 }, position: 'relative', zIndex: 1 }}
>
<Stack sx={{ gap: 5 }}>
<Stack direction="row" sx={{ alignItems: 'center', gap: 1 }}>
<Chip
label={label}
variant="outlined"
slotProps={{ label: { sx: { py: 0.75, px: 2, typography: 'caption', color: 'secondary.main' } } }}
sx={{ borderColor: 'grey.600' }}
/>
<Divider sx={{ width: 63, borderBottomWidth: 2 }} />
</Stack>
<Typeset {...{ heading, caption, captionProps: { sx: { maxWidth: 478 } } }} />
</Stack>
{input && typeof input === 'object' && (
<Stack sx={{ gap: 0.75, width: { sm: '100%', md: 'unset' } }}>
<OutlinedInput
placeholder={input.placeholder || 'Enter your email address'}
endAdornment={
<Button
color="primary"
variant="contained"
sx={{ px: 4, minWidth: { xs: 110, md: 120 } }}
{...input.adornmentBtn}
/>
}
slotProps={{
input: { 'aria-label': 'Email address', sx: { px: 2.5, py: 0.75 } },
notchedOutline: { sx: { borderRadius: 25 } }
}}
sx={{ typography: 'caption2', color: 'secondary.main', p: 0.5, whiteSpace: 'nowrap' }}
/>
{input.helpertext && (
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
{input.helpertext}
</Typography>
)}
</Stack>
)}
{(primaryBtn || secondaryBtn || description) && (
<Stack sx={{ alignItems: 'flex-start', gap: 1.5, width: { sm: '100%', md: '60%' }, ...(input && { mt: -6 }) }}>
{(primaryBtn || secondaryBtn) && (
<Stack direction="row" spacing={1.5} sx={{ alignItems: 'flex-start', justifyContent: 'center' }}>
{secondaryBtn && (
<ButtonAnimationWrapper>
<Button variant="outlined" sx={{ minWidth: { sm: 170 } }} {...secondaryBtn} />
</ButtonAnimationWrapper>
)}
{primaryBtn && (
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, ease: 'easeInOut' }}
whileHover={{ scale: 1.06 }}
>
<ButtonAnimationWrapper>
<Button variant="contained" sx={{ minWidth: { sm: 170 } }} {...primaryBtn} />
</ButtonAnimationWrapper>
</motion.div>
)}
</Stack>
)}
{description && typeof description === 'string' ? (
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
{description}
</Typography>
) : (
description
)}
</Stack>
)}
</Stack>
<Box
sx={{ position: 'absolute', right: -160, bottom: -160, display: { xs: 'none', md: 'block' }, transform: 'scaleX(-1)' }}
>
<LogoWatermark />
</Box>
</GraphicsCard>
</motion.div>
</Grid>
<Grid size={{ xs: 12, sm: 4, md: 3 }}>
<Grid container sx={{ height: 1, position: 'relative' }}>
<Grid size={{ xs: 6, sm: 12 }} sx={{ minHeight: { sm: '50%' } }}>
<GraphicsCard sx={{ height: 1 }}>
<Stack sx={{ alignItems: 'center', gap: 1, py: { xs: 2, sm: 6, md: 7.5 }, px: { xs: 2, sm: 3.5 }, textAlign: 'center' }}>
<Typography component="div" variant="h1">
{saleData.count}
<Typography variant="h2" component="span" sx={{ color: 'text.secondary' }}>
{saleData.defaultUnit}
</Typography>
</Typography>
<Typography sx={{ color: 'text.secondary' }}>{saleData.caption}</Typography>
</Stack>
</GraphicsCard>
</Grid>
<Box
sx={{
position: 'absolute',
left: '50%',
top: '50%',
transform: { xs: 'translate(-50%,-50%) rotate(90deg)', sm: 'translate(-50%,-50%)' },
'& .wave svg': { width: { xs: 70, sm: 122 } }
}}
>
<Wave />
</Box>
<Grid size={{ xs: 6, sm: 12 }} sx={{ minHeight: { sm: '50%' } }}>
<GraphicsCard sx={{ height: 1 }}>
<ProfileGroup
{...profileGroups}
sx={{
py: { xs: 2, sm: 4, md: 6.75 },
px: { xs: 2, sm: 1.5 },
height: 1,
alignItems: 'center',
justifyContent: 'center',
textAlign: 'center',
'& .MuiAvatarGroup-root': { mb: 0.5 },
'& .MuiAvatar-root': { width: { xs: 40, sm: 58 }, height: { xs: 40, sm: 58 } },
'& .wave': { display: 'none' }
}}
/>
</GraphicsCard>
</Grid>
</Grid>
</Grid>
</Grid>
</motion.div>
</ContainerWrapper>
);
}
Cta5.propTypes = {
heading: PropTypes.string,
caption: PropTypes.string,
label: PropTypes.string,
input: PropTypes.oneOfType([PropTypes.bool, PropTypes.any]),
primaryBtn: PropTypes.any,
secondaryBtn: PropTypes.any,
description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
saleData: PropTypes.any,
profileGroups: PropTypes.object
};
@@ -0,0 +1,2 @@
export { default as Cta4 } from './Cta4';
export { default as Cta5 } from './Cta5';