Skip to content

Commit 1ff2e2b

Browse files
committed
Add doorbell page
1 parent 1c6360b commit 1ff2e2b

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

app/doorbell/page.tsx

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
"use client"
2+
import { useState, useEffect } from "react"
3+
import styled from "styled-components"
4+
import { motion } from "framer-motion"
5+
import { PotionBackground } from "../components/PotionBackground"
6+
import { ErrorBoundary } from "../components/ErrorBoundary"
7+
import { Button } from "../components/Button"
8+
9+
// Components //
10+
11+
export default function Doorbell() {
12+
const [isRinging, setIsRinging] = useState(false)
13+
14+
const handleDoorbellClick = () => {
15+
setIsRinging(true)
16+
}
17+
18+
useEffect(() => {
19+
if (isRinging) {
20+
const timer = setTimeout(() => {
21+
setIsRinging(false)
22+
}, 5000)
23+
return () => clearTimeout(timer)
24+
}
25+
}, [isRinging])
26+
27+
return (
28+
<>
29+
<BackgroundContainer>
30+
<ErrorBoundary
31+
fallback={<div style={{ backgroundColor: "black", width: "100%", height: "100%" }} />}
32+
>
33+
<PotionBackground />
34+
</ErrorBoundary>
35+
</BackgroundContainer>
36+
<Main $ignoreHeader>
37+
<Hero>
38+
<HeadingSection>
39+
<Heading>Welcome to</Heading>
40+
<Logo src="/images/sd-devx-brand.png" alt="DEVxSD" />
41+
</HeadingSection>
42+
<ParagraphSection>
43+
<Paragraph>Ring the doorbell to enter the event.</Paragraph>
44+
</ParagraphSection>
45+
<ButtonSection>
46+
{isRinging ? (
47+
<AnimatedButtonContent
48+
animate={{
49+
scale: [1, 2, 1],
50+
x: [0, -10, 10, -5, 5, 0],
51+
rotate: [0, -10, 10, -5, 5, 0]
52+
}}
53+
transition={{
54+
duration: 0.5,
55+
ease: "easeInOut"
56+
}}
57+
>
58+
🛎️
59+
</AnimatedButtonContent>
60+
) : (
61+
<Button size="default" onClick={handleDoorbellClick}>
62+
Ring Doorbell
63+
</Button>
64+
)}
65+
</ButtonSection>
66+
</Hero>
67+
</Main>
68+
</>
69+
)
70+
}
71+
72+
// Styled Components //
73+
74+
const Main = styled.main<{ $ignoreHeader?: boolean }>`
75+
margin-top: ${({ $ignoreHeader = false }) => ($ignoreHeader ? "-72px" : "0")};
76+
color: white;
77+
display: flex;
78+
flex-direction: column;
79+
align-items: center;
80+
justify-content: center;
81+
`
82+
83+
const BackgroundContainer = styled.section`
84+
background-color: #0a0a0a;
85+
position: fixed;
86+
height: 100vh;
87+
width: 100vw;
88+
top: 0;
89+
left: 0;
90+
display: flex;
91+
flex-direction: column;
92+
align-items: center;
93+
justify-content: center;
94+
`
95+
96+
const Hero = styled.section`
97+
position: relative;
98+
height: 100vh;
99+
width: 100vw;
100+
display: flex;
101+
flex-direction: column;
102+
align-items: center;
103+
justify-content: center;
104+
gap: 3rem;
105+
`
106+
107+
const HeadingSection = styled.section`
108+
display: flex;
109+
flex-direction: column;
110+
align-items: center;
111+
justify-content: center;
112+
gap: 1rem;
113+
padding: 0 3rem;
114+
`
115+
116+
const Heading = styled.h1`
117+
font-size: clamp(2rem, 8vw, 4rem);
118+
font-weight: 700;
119+
margin: 0;
120+
text-align: center;
121+
`
122+
123+
const Logo = styled.img`
124+
width: 100%;
125+
max-width: 688px;
126+
margin: 0 auto;
127+
`
128+
129+
const ParagraphSection = styled.section`
130+
padding: 0 3rem;
131+
`
132+
133+
const Paragraph = styled.p`
134+
font-size: 1.25rem;
135+
text-align: center;
136+
max-width: 1024px;
137+
margin: 0;
138+
`
139+
140+
const ButtonSection = styled.section`
141+
display: flex;
142+
justify-content: center;
143+
align-items: center;
144+
`
145+
146+
const AnimatedButtonContent = styled(motion.span)`
147+
display: inline-block;
148+
font-size: 2rem;
149+
line-height: 1.5;
150+
`

0 commit comments

Comments
 (0)