Add a simple notification component

This commit is contained in:
Arkaprabha Chakraborty
2024-08-12 12:52:35 +05:30
parent bf7181ec2b
commit a205fcd978
2 changed files with 69 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
import axios from "axios"; import axios from "axios";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import Confetti from "react-confetti"; import Confetti from "react-confetti";
import Notification from "./Notification";
const DownloadForm = () => { const DownloadForm = () => {
const [url, setUrl] = useState(""); const [url, setUrl] = useState("");
@@ -10,6 +11,7 @@ const DownloadForm = () => {
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [isDownloading, setIsDownloading] = useState(false); const [isDownloading, setIsDownloading] = useState(false);
const [showConfetti, setShowConfetti] = useState(false); const [showConfetti, setShowConfetti] = useState(false);
const [notification, setNotification] = useState(null);
const isValidYouTubeUrl = (url) => { const isValidYouTubeUrl = (url) => {
const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+$/; const youtubeRegex = /^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.be)\/.+$/;
@@ -20,10 +22,10 @@ const DownloadForm = () => {
e.preventDefault(); e.preventDefault();
if (!url) { if (!url) {
setMessage("maybe enter an URL first"); setNotification("Maybe enter an URL first");
return; return;
} else if (!isValidYouTubeUrl(url)) { } else if (!isValidYouTubeUrl(url)) {
setMessage("doesn't look like YouTube to me"); setNotification("Doesn't look like YouTube to me");
return; return;
} }
@@ -162,13 +164,13 @@ const DownloadForm = () => {
{!isDownloading && !message.startsWith("Downloading") && ( {!isDownloading && !message.startsWith("Downloading") && (
<button <button
type="submit" type="submit"
className="relative inline-flex items-center px-8 py-4 text-lg font-bold rounded-xl text-white bg-black bg-opacity-60 hover:shadow-lg focus:outline-none transition-all duration-300" className="relative inline-flex items-center px-10 py-6 text-2xl font-bold rounded-2xl text-black bg-white bg-opacity-60 hover:shadow-lg focus:outline-none transition-all duration-300"
> >
<span className="absolute inset-0 bg-black opacity-0 transition-opacity duration-300 ease-in-out active:opacity-40 rounded-xl"></span> <span className="absolute inset-0 bg-black opacity-0 transition-opacity duration-300 ease-in-out active:opacity-40 rounded-xl"></span>
Download Download
</button> </button>
)} )}
</div>{" "} </div>
</form> </form>
{showConfetti && ( {showConfetti && (
@@ -185,6 +187,12 @@ const DownloadForm = () => {
/> />
</div> </div>
)} )}
{notification && (
<Notification
message={notification}
onClose={() => setNotification(null)}
/>
)}
<style jsx>{` <style jsx>{`
@keyframes loading { @keyframes loading {
0% { 0% {

View File

@@ -0,0 +1,57 @@
import React, { useEffect, useState } from "react";
const Notification = ({ message, onClose }) => {
const [fade, setFade] = useState(false);
useEffect(() => {
const fadeOutTimer = setTimeout(() => setFade(true), 4800);
const closeTimer = setTimeout(onClose, 5000);
return () => {
clearTimeout(fadeOutTimer);
clearTimeout(closeTimer);
};
}, [onClose]);
return (
<div
className={`fixed top-20 right-4 z-50 ${
fade ? "animate-fadeOut" : "animate-slideIn"
}`}
onClick={onClose}
>
<div className="bg-amber-600 text-white px-4 py-2 rounded shadow-lg cursor-pointer">
{message}
</div>
<style jsx>{`
.animate-slideIn {
animation: slideIn 0.5s ease-out;
}
.animate-fadeOut {
animation: fadeOut 0.2s ease-in forwards;
}
@keyframes slideIn {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
`}</style>
</div>
);
};
export default Notification;