Skip to content

Commit

Permalink
added credit card
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephen-Gordon committed Mar 25, 2024
1 parent 79020e0 commit a4ec10d
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 23 deletions.
29 changes: 29 additions & 0 deletions src/app/components/CreditCard/CreditCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import useGetAddress from "@/app/hooks/useGetAddress";
import Balance from "../Balance/Balance";
import { HoverBorderGradient } from "../ui/hover-border-gradient";
import { TextGenerateEffect } from "../ui/text-generate-effect";
import truncateEthAddress from "truncate-eth-address";

export default function CreditCard() {

const address = useGetAddress();

return (
<>
<HoverBorderGradient className='relative grid h-52 w-full rounded-xl shadow-lg'>
<div className='to-tr absolute -z-50 h-full w-full rounded-xl bg-transparent bg-gradient-to-r from-slate-50/10 backdrop-blur-xl'>
<></>
</div>

<div className='absolute z-50 grid h-full w-full content-center items-center justify-center p-2 text-center text-5xl text-black/80 mix-blend-exclusion dark:text-white/80'>
<TextGenerateEffect words='$56'></TextGenerateEffect>
</div>
<div className='absolute z-50 mb-auto grid h-full w-full content-end p-4'>
<div className='text-muted-foreground mb-auto grid h-full content-end justify-start text-base mix-blend-exclusion'>
{truncateEthAddress(address as string)}
</div>
</div>
</HoverBorderGradient>
</>
);
}
4 changes: 2 additions & 2 deletions src/app/components/addAContact/addAContact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default function AddAContact({
style={{ width: '100%' }}
value={newContactName}
placeholder='Name'
className='w-full'
className='w-full text-base'
/>
</div>
{payee == '' && (
Expand All @@ -119,7 +119,7 @@ export default function AddAContact({
name='address'
value={newContactAddress}
placeholder='Address'
className='w-full'
className='w-full text-base'
/>
</div>

Expand Down
14 changes: 7 additions & 7 deletions src/app/components/ui/background-gradient-animation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { useInView, motion, useScroll, useTransform } from 'framer-motion';
export const BackgroundGradientAnimation = ({
gradientBackgroundStart = 'rgb(108, 0, 162)',
gradientBackgroundEnd = 'rgb(0, 17, 82)',
firstColor = '228, 83, 104',
firstColor = '9, 69, 223',
secondColor = '9, 69, 223',
thirdColor = '223, 9, 9',
fourthColor = '200, 50, 50',
fifthColor = '180, 180, 50',
pointerColor = '140, 100, 255',
thirdColor = '9, 69, 223',
fourthColor = '9, 69, 223',
fifthColor = '9, 69, 223',
pointerColor = '9, 69, 223',
size = '80%',
blendingValue = 'hard-light',
children,
Expand Down Expand Up @@ -43,7 +43,7 @@ export const BackgroundGradientAnimation = ({

let { scrollYProgress } = useScroll();
let y = useTransform(scrollYProgress, [0, 1], ['0', '-50%']);
let opacity = useTransform(scrollYProgress, [0, 0.7], [0.7, 0]);
let opacity = useTransform(scrollYProgress, [0, 0.6], [0.6, 0]);
let scale = useTransform(scrollYProgress, [0, 1], ['100%', '20%']);
let scale2 = useTransform(scrollYProgress, [0, 1], ['100%', '60%']);

Expand Down Expand Up @@ -97,7 +97,7 @@ export const BackgroundGradientAnimation = ({
return (
<div
className={cn(
'bg-background relative left-0 top-0 h-screen w-screen overflow-hidden opacity-30',
'bg-background relative left-0 top-0 h-screen w-screen overflow-hidden opacity-20',
containerClassName
)}
>
Expand Down
103 changes: 103 additions & 0 deletions src/app/components/ui/hover-border-gradient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
'use client';
import React, { useState, useEffect, useRef } from 'react';

import { motion } from 'framer-motion';
import { cn } from '@/lib/utils';
type Direction = 'TOP' | 'LEFT' | 'BOTTOM' | 'RIGHT';

export function HoverBorderGradient({
children,
containerClassName,
className,
as: Tag = 'button',
duration = 1,
clockwise = true,
...props
}: React.PropsWithChildren<
{
as?: React.ElementType;
containerClassName?: string;
className?: string;
duration?: number;
clockwise?: boolean;
} & React.HTMLAttributes<HTMLElement>
>) {
const [hovered, setHovered] = useState<boolean>(false);
const [direction, setDirection] = useState<Direction>('TOP');

const rotateDirection = (currentDirection: Direction): Direction => {
const directions: Direction[] = ['TOP', 'LEFT', 'BOTTOM', 'RIGHT'];
const currentIndex = directions.indexOf(currentDirection);
const nextIndex = clockwise
? (currentIndex - 1 + directions.length) % directions.length
: (currentIndex + 1) % directions.length;
return directions[nextIndex];
};

const movingMap: Record<Direction, string> = {
TOP: 'radial-gradient(20.7% 50% at 50% 0%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)',
LEFT: 'radial-gradient(16.6% 43.1% at 0% 50%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)',
BOTTOM:
'radial-gradient(20.7% 50% at 50% 100%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)',
RIGHT:
'radial-gradient(16.2% 41.199999999999996% at 100% 50%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)',
};

const highlight =
'radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)';

useEffect(() => {
if (!hovered) {
const interval = setInterval(() => {
setDirection((prevState) => rotateDirection(prevState));
}, duration * 1000);
return () => clearInterval(interval);
}
}, [hovered]);
return (
<Tag
onClick={(event: React.MouseEvent<HTMLDivElement>) => {
setHovered(!hovered);
}}
/* onMouseEnter={(event: React.MouseEvent<HTMLDivElement>) => {
setHovered(true);
}} */
/* onMouseLeave={() => setHovered(false)} */
className={cn(
`relative flex h-min w-full flex-col flex-nowrap content-center items-center justify-center gap-10 overflow-visible rounded-xl border bg-black/${
hovered ? 10 : 0
} decoration-clone p-px transition duration-500 dark:bg-white/20`,
containerClassName
)}
{...props}
>
<div
className={cn(
'z-40 w-auto rounded-[inherit] bg-black px-4 py-2',
className
)}
>
{children}
</div>
<motion.div
className={cn(
'absolute inset-0 z-0 flex-none overflow-hidden rounded-[inherit]'
)}
style={{
filter: 'blur(2px)',
position: 'absolute',
width: '100%',
height: '100%',
}}
initial={{ background: movingMap[direction] }}
animate={{
background: hovered
? [movingMap[direction], highlight]
: movingMap[direction],
}}
transition={{ ease: 'linear', duration: duration ?? 1 }}
/>
<div className='z-30 absolute inset-[2px] flex-none rounded-[100px] bg-black' />
</Tag>
);
}
92 changes: 92 additions & 0 deletions src/app/components/ui/lamp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
'use client';
import React from 'react';
import { motion } from 'framer-motion';
import { cn } from '@/lib/utils';
export function LampDemo() {
return (
<LampContainer>

</LampContainer>
);
}

export const LampContainer = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<div
className={cn(
'relative z-0 flex min-h-screen w-full flex-col items-center justify-center overflow-hidden rounded-md bg-slate-950',
className
)}
>
<div className='relative isolate z-0 flex w-full flex-1 scale-y-125 items-center justify-center '>
<motion.div
initial={{ opacity: 0.5, width: '15rem' }}
whileInView={{ opacity: 1, width: '30rem' }}
transition={{
delay: 0.3,
duration: 0.8,
ease: 'easeInOut',
}}
style={{
backgroundImage: `conic-gradient(var(--conic-position), var(--tw-gradient-stops))`,
}}
className='bg-gradient-conic absolute inset-auto right-1/2 h-56 w-[30rem] overflow-visible from-cyan-500 via-transparent to-transparent text-white [--conic-position:from_70deg_at_center_top]'
>
<div className='absolute bottom-0 left-0 z-20 h-40 w-[100%] bg-slate-950 [mask-image:linear-gradient(to_top,white,transparent)]' />
<div className='absolute bottom-0 left-0 z-20 h-[100%] w-40 bg-slate-950 [mask-image:linear-gradient(to_right,white,transparent)]' />
</motion.div>
<motion.div
initial={{ opacity: 0.5, width: '15rem' }}
whileInView={{ opacity: 1, width: '30rem' }}
transition={{
delay: 0.3,
duration: 0.8,
ease: 'easeInOut',
}}
style={{
backgroundImage: `conic-gradient(var(--conic-position), var(--tw-gradient-stops))`,
}}
className='bg-gradient-conic absolute inset-auto left-1/2 h-56 w-[30rem] from-transparent via-transparent to-cyan-500 text-white [--conic-position:from_290deg_at_center_top]'
>
<div className='absolute bottom-0 right-0 z-20 h-[100%] w-40 bg-slate-950 [mask-image:linear-gradient(to_left,white,transparent)]' />
<div className='absolute bottom-0 right-0 z-20 h-40 w-[100%] bg-slate-950 [mask-image:linear-gradient(to_top,white,transparent)]' />
</motion.div>
<div className='absolute top-1/2 h-48 w-full translate-y-12 scale-x-150 bg-slate-950 blur-2xl'></div>
<div className='absolute top-1/2 z-50 h-48 w-full bg-transparent opacity-10 backdrop-blur-md'></div>
<div className='absolute inset-auto z-50 h-36 w-[28rem] -translate-y-1/2 rounded-full bg-cyan-500 opacity-50 blur-3xl'></div>
<motion.div
initial={{ width: '8rem' }}
whileInView={{ width: '16rem' }}
transition={{
delay: 0.3,
duration: 0.8,
ease: 'easeInOut',
}}
className='absolute inset-auto z-30 h-36 w-64 -translate-y-[6rem] rounded-full bg-cyan-400 blur-2xl'
></motion.div>
<motion.div
initial={{ width: '15rem' }}
whileInView={{ width: '30rem' }}
transition={{
delay: 0.3,
duration: 0.8,
ease: 'easeInOut',
}}
className='absolute inset-auto z-50 h-0.5 w-[30rem] -translate-y-[7rem] bg-cyan-400 '
></motion.div>

<div className='absolute inset-auto z-40 h-44 w-full -translate-y-[12.5rem] bg-slate-950 '></div>
</div>

<div className='relative z-50 flex -translate-y-80 flex-col items-center px-5'>

</div>
</div>
);
};
4 changes: 2 additions & 2 deletions src/app/components/ui/text-generate-effect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const TextGenerateEffect = ({
return (
<motion.span
key={word + idx}
className='text-black opacity-0 dark:text-white'
className='opacity-0 '
>
{word}{' '}
</motion.span>
Expand All @@ -43,7 +43,7 @@ export const TextGenerateEffect = ({

return (
<div className={cn('font-bold', className)}>
<div className=' text-inherit font-inherit leading-snug tracking-wide text-black dark:text-white'>
<div className=' font-inherit leading-snug tracking-wide text-inherit mix-blend-exclusion '>
{renderWords()}
</div>
</div>
Expand Down
19 changes: 7 additions & 12 deletions src/app/home/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import { motion, useScroll, useTransform } from 'framer-motion';
import useGetTokenBalance from '../hooks/useGetTokenBalance';
import AuthPage from '../components/AuthPage/AuthPage';
import { setContacts } from '@/GlobalRedux/Features/contacts/contactsSlice';
import CreditCard from '../components/CreditCard/CreditCard';
import { LampDemo } from '../components/ui/lamp';

export default function Page() {
// privy
Expand Down Expand Up @@ -100,27 +102,19 @@ export default function Page() {
<AuthPage>
<div id='render' className='min-h-[150vh]'>
<div className='absolute right-4 top-4'>
<Link
/* onClick={() => {
dispatch(setSheet(true));
}} */ href={{
pathname: '/menu',
query: { isNavOpen: true },
}}
>
<Menu onClick={() => router.push(`/menu?isNavOpen=true`)} />
</Link>

</div>
<div className='blurios'>
<div className='absolute -z-50 '>
<BackgroundGradientAnimation />
</div>
<motion.div
style={{ y, scale, opacity }}
className='items-center p-2 pt-40 text-center text-5xl mix-blend-exclusion'
className='items-center p-2 text-center text-5xl mix-blend-exclusion'
>
<Balance />
{/* <Balance /> */}
{/* {address} */}
<CreditCard />
</motion.div>

<motion.div
Expand Down Expand Up @@ -174,6 +168,7 @@ export default function Page() {
</div>
</motion.div>
<div className='bg-accent/90 relative mt-4 w-full rounded-t-3xl bg-opacity-10 bg-clip-padding p-4 backdrop-blur-sm backdrop-filter'>

{/* <Tab.Group>
<Tab.List>
<div className='mb-4 flex justify-between'>
Expand Down

0 comments on commit a4ec10d

Please sign in to comment.