Skip to content

Commit 5c45633

Browse files
committed
edited banner and header animations, still need to work on closing banner when header is visible.
1 parent 964080a commit 5c45633

File tree

10 files changed

+283
-60
lines changed

10 files changed

+283
-60
lines changed

frontend/src/components/ApplicationBanner/ApplicationBanner.tsx

+31-20
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,48 @@
11
// src/components/ApplicationBanner.jsx
2-
import './styles.scss';
3-
// src/components/ApplicationBanner.jsx
4-
import { useEffect } from 'react';
2+
import { useEffect, useState } from 'react';
53
import { useBanner } from '@/context/BannerContext';
4+
import './styles.scss';
5+
// import { Button } from '@/components/ui/moving-border'; - Implement moving border effect when hovered, also add fade-in for the border
66

77
const ApplicationBanner = () => {
8-
const { setBannerVisible } = useBanner();
8+
const { isBannerVisible, setBannerVisibility, hideBanner } = useBanner();
9+
const [isAnimating, setIsAnimating] = useState(false);
910

1011
useEffect(() => {
11-
setBannerVisible(true);
12-
return () => setBannerVisible(false);
13-
}, [setBannerVisible]);
12+
setBannerVisibility(true);
13+
return () => setBannerVisibility(false);
14+
}, [setBannerVisibility]);
15+
16+
const handleClose = () => {
17+
setIsAnimating(true);
18+
setTimeout(() => {
19+
hideBanner();
20+
setIsAnimating(false);
21+
}, 500); // Duration of the fade out animation
22+
};
23+
24+
if (!isBannerVisible) {
25+
return null;
26+
}
1427

1528
return (
16-
<div className="fixed top-0 left-0 w-full bg-blue-500 text-white text-center p-2 z-100">
29+
<div className={`fixed top-0 left-0 w-full bg-gradient-to-r from-blue-500 to-purple-500 backdrop:blur-md text-white text-center p-2 z-100
30+
${
31+
isAnimating ? 'fade-out-up' : ''
32+
}`}>
1733
<span className="font-bold">Last-minute call for our 2024 summer application!</span>
1834
<button onClick={() => window.location.href='/application-form'}
1935
aria-label="Apply Now"
20-
className="ml-6 inline-flex h-8 animate-shimmer items-center justify-center rounded-md border border-slate-800 bg-[linear-gradient(110deg,#000103,45%,#1e2631,55%,#000103)] bg-[length:200%_100%] px-6 font-medium text-slate-200 transition-colors focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 focus:ring-offset-slate-50 hover:bg-[linear-gradient(90deg, #6366f1, #a855f7)]" >
36+
className="ml-6 inline-flex h-8 animate-shimmer items-center justify-center rounded-md border border-slate-800 bg-[linear-gradient(110deg,#000103,45%,#343b45,55%,#000103)] bg-[length:200%_100%] px-6 font-medium text-slate-100
37+
focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 focus:ring-offset-slate-50
38+
backdrop-blur-sm hover:shadow-[0px_0px_4px_4px_rgba(0,0,0,0.15)] bg-white/[0.2] text-sm transition duration-200" >
2139
Apply Now
22-
</button>
40+
</button>
41+
<div className='justify-self-end w-8 bg-transparent absolute right-4 mx-2 text-center align-middle transition '>
42+
<button className="text-3xl font-white pt-[3px]" aria-label='Close' onClick={handleClose}>×</button>
43+
</div>
2344
</div>
2445
);
2546
};
2647

2748
export default ApplicationBanner;
28-
29-
30-
<button className="p-[3px] relative">
31-
<div className="ml-6 inline-flex h-8 px-6 justify-center rounded-lg absolute inset-0 bg-gradient-to-r from-indigo-500 to-purple-500">
32-
<div onClick={() => window.location.href='/application-form'}
33-
className="px-8 py-2 rounded-[6px] relative group transition duration-200 hover:bg-transparent animate-shimmer items-center border border-slate-800 bg-[linear-gradient(110deg,#000103,45%,#1e2631,55%,#000103)] bg-[length:200%_100%] font-medium text-slate-400 focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 focus:ring-offset-slate-50">
34-
Apply Now
35-
</div>
36-
</div>
37-
</button>

frontend/src/components/ApplicationBanner/styles.scss

+18-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,21 @@
1111

1212
.custom-bg-gradient {
1313
background: linear-gradient(110deg, #000103 45%, #1e2631 55%, #000103);
14-
}
14+
}
15+
16+
// src/components/styles.scss
17+
@keyframes fadeOutUp {
18+
from {
19+
opacity: 1;
20+
transform: translateY(0);
21+
}
22+
to {
23+
opacity: 0;
24+
transform: translateY(-100%);
25+
}
26+
}
27+
28+
.fade-out-up {
29+
animation: fadeOutUp 0.5s forwards;
30+
}
31+

frontend/src/components/Header/Header.scss

+25-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@
88

99
}
1010

11+
@keyframes slideUp {
12+
from {
13+
transform: translateY(56px); // Start from the position you want to animate up from
14+
}
15+
to {
16+
transform: translateY(0); // Slide up to its normal position
17+
}
18+
}
19+
20+
.slide-up {
21+
animation: slideUp 5s forwards;
22+
}
23+
24+
1125
.header-light{
1226
background: linear-gradient(to top, #fff, #fff);
1327
};
@@ -17,17 +31,17 @@
1731
};
1832

1933

20-
@keyframes fadeInLeft {
21-
from {
22-
opacity: 0;
23-
transform: scaleX(0);
24-
transform-origin: left;
25-
}
26-
to {
27-
opacity: 1;
28-
transform: scaleX(1%);
29-
}
30-
}
34+
// @keyframes fadeInLeft {
35+
// from {
36+
// opacity: 0;
37+
// transform: scaleX(0);
38+
// transform-origin: left;
39+
// }
40+
// to {
41+
// opacity: 1;
42+
// transform: scaleX(1%);
43+
// }
44+
// }
3145

3246

3347

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import "../../styles/App.scss";
22
import "./Header.scss";
3+
import { useState, useEffect } from "react";
34
import getMode from "../../utils/getMode";
4-
import { Link } from "@tanstack/react-router";
55
import { useBanner } from "@/context/BannerContext";
6+
import StyledLink from "./StyledLink";
67

78
const Header = () => {
89
const mode = getMode();
910
const { isBannerVisible } = useBanner();
11+
const [isAnimating, setIsAnimating] = useState(false);
1012

11-
//TODO: remove this and change to dark:text-white, etc.
12-
const headerClass = ` p-4 ${isBannerVisible ? 'mt-16' : ''} hidden `;
13-
const navClass = `mt-2 ${mode === "dark" ? "header-text-dark text-white" : "header-text-light text-black"}`; // add fonts
13+
useEffect(() => {
14+
if (!isBannerVisible) {
15+
setIsAnimating(true);
16+
setTimeout(() => {
17+
setIsAnimating(false);
18+
}, 500); // Duration of the slide up animation
19+
}
20+
}, [isBannerVisible]);
21+
22+
//TODO: remove this (${mode === "dark" ? "header-text-dark text-white" : "header-text-light text-black"}) and change to dark:text-white, etc.
23+
const headerClass = ` p-4 ${isBannerVisible ? 'mt-12' : ''} ${isAnimating ? 'slide-up' : '' } hidden `;
24+
const navClass = `mt-2 `; // add fonts
1425

1526
return (
1627
<header className={headerClass}>
@@ -32,15 +43,3 @@ const Header = () => {
3243
};
3344

3445
export default Header;
35-
36-
function StyledLink({ address, text }) {
37-
return (
38-
<Link
39-
to={address}
40-
className="relative mx-1 p-2 bg-white overflow-hidden group"
41-
>
42-
<span className="relative z-10">{text}</span>
43-
<div className="absolute rounded-md inset-0 bg-gradient-to-r from-cyan-300 to-purple-300 transition-transform duration-300 transform scale-x-0 group-hover:scale-x-100 origin-left"></div>
44-
</Link>
45-
);
46-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// src/components/StyledLink.tsx
2+
import { Link } from "@tanstack/react-router";
3+
4+
interface StyledLinkProps {
5+
address: string;
6+
text: string;
7+
}
8+
9+
const StyledLink: React.FC<StyledLinkProps> = ({ address, text }) => {
10+
return (
11+
<Link
12+
to={address}
13+
className="relative mx-1 p-2 bg-white overflow-hidden group"
14+
>
15+
<span className="relative z-10">{text}</span>
16+
<div className="absolute rounded-md inset-0 bg-gradient-to-r from-cyan-300 to-purple-300 transition-transform duration-300 transform scale-x-0 group-hover:scale-x-100 origin-left"></div>
17+
</Link>
18+
);
19+
};
20+
21+
export default StyledLink;
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"use client";
2+
// Use acutal examples
3+
4+
import { CardStack } from "@/components/ui/card-stack";
5+
import { cn } from "@/utils/cn";
6+
export function CardStackDemo() {
7+
return (
8+
<div className="h-[40rem] flex items-center justify-center w-full">
9+
<CardStack items={CARDS} />
10+
</div>
11+
);
12+
}
13+
14+
// Small utility to highlight the content of specific section of a testimonial content
15+
export const Highlight = ({
16+
children,
17+
className,
18+
}: {
19+
children: React.ReactNode;
20+
className?: string;
21+
}) => {
22+
return (
23+
<span
24+
className={cn(
25+
"font-bold bg-emerald-100 text-emerald-700 dark:bg-emerald-700/[0.2] dark:text-emerald-500 px-1 py-0.5",
26+
className
27+
)}
28+
>
29+
{children}
30+
</span>
31+
);
32+
};
33+
34+
const CARDS = [
35+
{
36+
id: 0,
37+
name: "Manu Arora",
38+
designation: "Senior Software Engineer",
39+
content: (
40+
<p>
41+
These cards are amazing, <Highlight>I want to use them</Highlight> in my
42+
project. Framer motion is a godsend ngl tbh fam 🙏
43+
</p>
44+
),
45+
},
46+
{
47+
id: 1,
48+
name: "Elon Musk",
49+
designation: "Senior Shitposter",
50+
content: (
51+
<p>
52+
I dont like this Twitter thing,{" "}
53+
<Highlight>deleting it right away</Highlight> because yolo. Instead, I
54+
would like to call it <Highlight>X.com</Highlight> so that it can easily
55+
be confused with adult sites.
56+
</p>
57+
),
58+
},
59+
{
60+
id: 2,
61+
name: "Tyler Durden",
62+
designation: "Manager Project Mayhem",
63+
content: (
64+
<p>
65+
The first rule of
66+
<Highlight>Fight Club</Highlight> is that you do not talk about fight
67+
club. The second rule of
68+
<Highlight>Fight club</Highlight> is that you DO NOT TALK about fight
69+
club.
70+
</p>
71+
),
72+
},
73+
];
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"use client";
2+
import { useEffect, useState } from "react";
3+
import { motion } from "framer-motion";
4+
5+
let interval: any;
6+
7+
type Card = {
8+
id: number;
9+
name: string;
10+
designation: string;
11+
content: React.ReactNode;
12+
};
13+
14+
export const CardStack = ({
15+
items,
16+
offset,
17+
scaleFactor,
18+
}: {
19+
items: Card[];
20+
offset?: number;
21+
scaleFactor?: number;
22+
}) => {
23+
const CARD_OFFSET = offset || 10;
24+
const SCALE_FACTOR = scaleFactor || 0.06;
25+
const [cards, setCards] = useState<Card[]>(items);
26+
27+
useEffect(() => {
28+
startFlipping();
29+
30+
return () => clearInterval(interval);
31+
}, []);
32+
const startFlipping = () => {
33+
interval = setInterval(() => {
34+
setCards((prevCards: Card[]) => {
35+
const newArray = [...prevCards]; // create a copy of the array
36+
newArray.unshift(newArray.pop()!); // move the last element to the front
37+
return newArray;
38+
});
39+
}, 5000);
40+
};
41+
42+
return (
43+
<div className="relative h-60 w-60 md:h-60 md:w-96">
44+
{cards.map((card, index) => {
45+
return (
46+
<motion.div
47+
key={card.id}
48+
className="absolute dark:bg-black bg-white h-60 w-60 md:h-60 md:w-96 rounded-3xl p-4 shadow-xl border border-neutral-200 dark:border-white/[0.1] shadow-black/[0.1] dark:shadow-white/[0.05] flex flex-col justify-between"
49+
style={{
50+
transformOrigin: "top center",
51+
}}
52+
animate={{
53+
top: index * -CARD_OFFSET,
54+
scale: 1 - index * SCALE_FACTOR, // decrease scale for cards that are behind
55+
zIndex: cards.length - index, // decrease z-index for the cards that are behind
56+
}}
57+
>
58+
<div className="font-normal text-neutral-700 dark:text-neutral-200">
59+
{card.content}
60+
</div>
61+
<div>
62+
<p className="text-neutral-500 font-medium dark:text-white">
63+
{card.name}
64+
</p>
65+
<p className="text-neutral-400 font-normal dark:text-neutral-200">
66+
{card.designation}
67+
</p>
68+
</div>
69+
</motion.div>
70+
);
71+
})}
72+
</div>
73+
);
74+
};

frontend/src/components/ui/moving-border.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,8 @@ export const MovingBorder = ({
145145
</>
146146
);
147147
};
148+
149+
150+
<button className="px-4 py-2 text-black backdrop-blur-sm border border-black rounded-md hover:shadow-[0px_0px_4px_4px_rgba(0,0,0,0.1)] bg-white/[0.2] text-sm transition duration-200">
151+
Backdrop blur
152+
</button>

0 commit comments

Comments
 (0)