mirror of
https://github.com/reiyua/TombayRetirementTimerV2.git
synced 2026-01-20 08:27:47 +00:00
Basic countdown setup, time to make it look good!
This commit is contained in:
parent
31018deee8
commit
2cf59226aa
2 changed files with 141 additions and 31 deletions
93
src/App.jsx
93
src/App.jsx
|
|
@ -1,35 +1,66 @@
|
||||||
import { useState } from 'react'
|
import React, { useState, useEffect } from 'react';
|
||||||
import reactLogo from './assets/react.svg'
|
import './Countdown.css';
|
||||||
import viteLogo from '/vite.svg'
|
|
||||||
import './App.css'
|
|
||||||
|
|
||||||
function App() {
|
const RetirementCountdown = () => {
|
||||||
const [count, setCount] = useState(0)
|
const [timeLeft, setTimeLeft] = useState({});
|
||||||
|
const [prevTimeLeft, setPrevTimeLeft] = useState({});
|
||||||
|
|
||||||
|
const calculateTimeLeft = () => {
|
||||||
|
const retirementDate = new Date('2025-09-02'); // Replace with your retirement date
|
||||||
|
const now = new Date();
|
||||||
|
const difference = retirementDate - now;
|
||||||
|
|
||||||
|
let timeLeft = {};
|
||||||
|
|
||||||
|
if (difference > 0) {
|
||||||
|
timeLeft = {
|
||||||
|
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
|
||||||
|
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
|
||||||
|
minutes: Math.floor((difference / 1000 / 60) % 60),
|
||||||
|
seconds: Math.floor((difference / 1000) % 60),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeLeft;
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
const newTimeLeft = calculateTimeLeft();
|
||||||
|
setPrevTimeLeft(timeLeft); // Store the previous time
|
||||||
|
setTimeLeft(newTimeLeft);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
}, [timeLeft]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="countdown-container">
|
||||||
<div>
|
<h1 className="countdown-title">Tombay retires in:</h1>
|
||||||
<a href="https://vitejs.dev" target="_blank">
|
{Object.keys(timeLeft).length > 0 ? (
|
||||||
<img src={viteLogo} className="logo" alt="Vite logo" />
|
<div className="countdown">
|
||||||
</a>
|
<FlipUnit number={timeLeft.days} prevNumber={prevTimeLeft.days} label="Days" />
|
||||||
<a href="https://react.dev" target="_blank">
|
<FlipUnit number={timeLeft.hours} prevNumber={prevTimeLeft.hours} label="Hours" />
|
||||||
<img src={reactLogo} className="logo react" alt="React logo" />
|
<FlipUnit number={timeLeft.minutes} prevNumber={prevTimeLeft.minutes} label="Minutes" />
|
||||||
</a>
|
<FlipUnit number={timeLeft.seconds} prevNumber={prevTimeLeft.seconds} label="Seconds" />
|
||||||
</div>
|
</div>
|
||||||
<h1>Vite + React</h1>
|
) : (
|
||||||
<div className="card">
|
<p>Congratulations! You're retired!</p>
|
||||||
<button onClick={() => setCount((count) => count + 1)}>
|
)}
|
||||||
count is {count}
|
</div>
|
||||||
</button>
|
);
|
||||||
<p>
|
};
|
||||||
Edit <code>src/App.jsx</code> and save to test HMR
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p className="read-the-docs">
|
|
||||||
Click on the Vite and React logos to learn more
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App
|
// FlipUnit component handles the animation for each unit
|
||||||
|
const FlipUnit = ({ number, prevNumber, label }) => {
|
||||||
|
return (
|
||||||
|
<div className="countdown-section">
|
||||||
|
<div className={`flip-card ${number !== prevNumber ? 'animate' : ''}`}>
|
||||||
|
<span className="countdown-number">{number}</span>
|
||||||
|
</div>
|
||||||
|
<span className="countdown-label">{label}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RetirementCountdown;
|
||||||
|
|
|
||||||
79
src/Countdown.css
Normal file
79
src/Countdown.css
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* Countdown Container */
|
||||||
|
.countdown-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh; /* Full viewport height */
|
||||||
|
width: 100vw; /* Full viewport width */
|
||||||
|
background-color: #282c34;
|
||||||
|
color: white;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Countdown Title */
|
||||||
|
.countdown-title {
|
||||||
|
font-size: 4em; /* Make the title larger */
|
||||||
|
margin-bottom: 40px; /* Add more space below the title */
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Countdown */
|
||||||
|
.countdown {
|
||||||
|
display: flex;
|
||||||
|
gap: 40px; /* Increase space between countdown sections */
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap; /* Ensure it wraps on smaller screens */
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1200px; /* Maximum width to avoid overcrowding */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Countdown Section (Days, Hours, Minutes, Seconds) */
|
||||||
|
.countdown-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flip Animation */
|
||||||
|
.flip-card {
|
||||||
|
perspective: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flip-card.animate .countdown-number {
|
||||||
|
animation: flip 0.6s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flip {
|
||||||
|
0% {
|
||||||
|
transform: rotateX(0deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotateX(-90deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotateX(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Countdown Number (Big Digital Style Numbers) */
|
||||||
|
.countdown-number {
|
||||||
|
font-size: 8em; /* Larger numbers */
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
padding: 30px; /* More padding around the numbers */
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.4);
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Countdown Label (Small Text under Numbers) */
|
||||||
|
.countdown-label {
|
||||||
|
font-size: 2em; /* Larger labels */
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in a new issue