From 90a88d5bc7477b4af3f26867217fa27e3bd57067 Mon Sep 17 00:00:00 2001 From: Technobot Date: Sat, 11 Apr 2026 19:13:36 +0700 Subject: [PATCH 1/3] feat: add animations, improve styling, update dependencies - Add 15+ CSS keyframe animations (fade-in, slide, bounce, float, pulse-glow, shimmer, etc.) - Add utility animation classes with stagger delays - Improve Navbar: glass effect on scroll, hover underline, smooth transitions - Improve TemplateLanding: animated hero text, floating image, CTA button - Improve GamesCard: crossfade image swap, hover glow, scale effect - Improve Features: card-based layout with icons, staggered animations - Improve Login: loading state, input focus animations, card entrance - Improve Footer: quick links section, hover effects, dynamic year - Improve PremiumCard: pulse-glow CTA, hover border effect - Fix App.css: add post card hover, button ripple, loading spinner, custom scrollbar - Update frontend dependencies to latest stable versions - Update backend dependencies to latest stable versions - Fix backend app.js: add error handler, uncomment module.exports, add dev script --- client/package.json | 20 +- client/src/App.css | 106 ++++++++ client/src/components/Features.js | 62 +++-- client/src/components/Footer.js | 36 ++- client/src/components/GamesCard.js | 66 +++-- client/src/components/Navbar.js | 32 ++- client/src/components/PremiumCard.js | 12 +- client/src/components/TemplateLanding.js | 26 +- client/src/index.css | 303 +++++++++++++++++++++++ client/src/pages/Login.js | 34 ++- server/express/app.js | 17 +- server/express/package.json | 31 +-- 12 files changed, 638 insertions(+), 107 deletions(-) diff --git a/client/package.json b/client/package.json index e12c614..564f142 100644 --- a/client/package.json +++ b/client/package.json @@ -4,20 +4,20 @@ "private": true, "dependencies": { "@cometchat-pro/chat": "^3.0.10", - "@sweetalert2/theme-borderless": "^5.0.15", + "@sweetalert2/theme-borderless": "^5.0.23", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", - "axios": "^1.2.0", - "daisyui": "^2.42.1", + "axios": "^1.7.9", + "daisyui": "^4.12.23", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-redux": "^8.0.5", + "react-redux": "^9.2.0", "react-router-dom": "^6.4.3", "react-scripts": "5.0.1", - "redux": "^4.2.0", - "redux-thunk": "^2.4.2", - "sweetalert2": "^11.6.15", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "sweetalert2": "^11.15.10", "web-vitals": "^2.1.4" }, "scripts": { @@ -45,8 +45,8 @@ ] }, "devDependencies": { - "autoprefixer": "^10.4.13", - "postcss": "^8.4.19", - "tailwindcss": "^3.2.4" + "autoprefixer": "^10.4.20", + "postcss": "^8.5.1", + "tailwindcss": "^3.4.17" } } diff --git a/client/src/App.css b/client/src/App.css index 049372a..d820cec 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -12,3 +12,109 @@ /* .option__videocall-group { display: none; } */ + +/* ========== POST CARD ANIMATIONS ========== */ +.post-card { + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.post-card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4); +} + +/* ========== BUTTON ANIMATIONS ========== */ +.btn-animated { + position: relative; + overflow: hidden; + transition: all 0.3s ease; +} + +.btn-animated::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 0; + background: rgba(255, 255, 255, 0.15); + border-radius: 50%; + transform: translate(-50%, -50%); + transition: width 0.6s ease, height 0.6s ease; +} + +.btn-animated:hover::after { + width: 300px; + height: 300px; +} + +.btn-animated:active { + transform: scale(0.95); +} + +/* ========== INPUT ANIMATIONS ========== */ +.input-animated { + transition: border-color 0.3s ease, box-shadow 0.3s ease; +} + +.input-animated:focus { + border-color: #D7385E; + box-shadow: 0 0 0 3px rgba(215, 56, 94, 0.2); +} + +/* ========== LOADING SPINNER ========== */ +.loading-spinner { + width: 50px; + height: 50px; + border: 4px solid rgba(215, 56, 94, 0.2); + border-top-color: #D7385E; + border-radius: 50%; + animation: spin-slow 0.8s linear infinite; +} + +@keyframes spin-slow { + to { + transform: rotate(360deg); + } +} + +/* ========== CARD ENTRANCE ========== */ +.card-entrance { + animation: fade-in-up 0.5s ease-out both; +} + +/* ========== NAVBAR GLASS ========== */ +.navbar-glass { + background: rgba(17, 16, 29, 0.8); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +/* ========== GAMES CARD CROSSFADE ========== */ +.games-card-img { + transition: opacity 0.4s ease, transform 0.4s ease; +} + +.games-card-overlay { + transition: opacity 0.3s ease; + backdrop-filter: blur(4px); +} + +/* ========== SCROLLBAR ========== */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: #11101d; +} + +::-webkit-scrollbar-thumb { + background: #D7385E; + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: #e84a6f; +} diff --git a/client/src/components/Features.js b/client/src/components/Features.js index 3bb0d8c..62df78d 100644 --- a/client/src/components/Features.js +++ b/client/src/components/Features.js @@ -1,27 +1,57 @@ import styles, { layout } from "../style"; function Features() { + const features = [ + { + title: "Smart Matchmaking", + desc: "Find match with our matchmaking system. Get paired with players who match your skill level and playstyle.", + icon: "🎯", + }, + { + title: "Real-time Communication", + desc: "Communicate with your team via chat, voice call*, or even video call*! Never miss a callout again.", + icon: "💬", + }, + { + title: "Share Your Moments", + desc: "Share your best gaming moments in a post. Build your gaming identity and connect with the community.", + icon: "📸", + }, + ]; + return (
-

HIGHLIGHT FEATURES

+

+ HIGHLIGHT FEATURES +

-
-
-

- Find match with our matchmaking system. Communicate with them via - chat, voice call *, or even video call *! -

-

- Share your moments playing with them in a post. -

-

- {" "} - * You can only make group & initiate a 1-on-1 call on - premium subcription. -

-
+
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

+ {feature.title} +

+

+ {feature.desc} +

+
+
+
+ ))} +

+ * You can only make group & initiate a 1-on-1 call on + premium subscription. +

); diff --git a/client/src/components/Footer.js b/client/src/components/Footer.js index 86a46af..770c209 100644 --- a/client/src/components/Footer.js +++ b/client/src/components/Footer.js @@ -1,26 +1,54 @@ import styles from "../style"; import teamupnologo from "../assets/teamupnologo.png"; + const Footer = () => { return (
teamup

Brought to you by gamers, for gamers.

+ +
+

+ Quick Links +

+
+ + Home + + + Login + + + Register + +
+
+ {/* copyright text */} -
+

- 2022 Jakarta. All Rights Reserved + {new Date().getFullYear()} Jakarta. All Rights Reserved

diff --git a/client/src/components/GamesCard.js b/client/src/components/GamesCard.js index ac6b3d3..ba612c7 100644 --- a/client/src/components/GamesCard.js +++ b/client/src/components/GamesCard.js @@ -1,36 +1,50 @@ +import { useState } from "react"; import { useNavigate } from "react-router-dom"; -const GamesCard = ({ game, gif }) => { +const GamesCard = ({ game, gif, index }) => { const navigation = useNavigate(); - function changePic1() { - document.getElementById(game.id).src = game.imgUrl; - } - function changePic2() { - document.getElementById(game.id).src = gif; - } + const [isHovered, setIsHovered] = useState(false); + return (
navigation("/login")} + onMouseEnter={() => setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} > - testinggame -
{ - changePic2(); - }} - onMouseOut={() => { - changePic1(); - }} - > -

- {game.name} -

+
+ {/* Base image */} + {game.name} + + {/* GIF overlay on hover */} + {`${game.name} + + {/* Overlay */} +
+

+ {game.name} +

+
+ + {/* Glow effect on hover */} +
); diff --git a/client/src/components/Navbar.js b/client/src/components/Navbar.js index e9149f0..afc1380 100644 --- a/client/src/components/Navbar.js +++ b/client/src/components/Navbar.js @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { close, menu } from "../assets"; import teamupnologo from "../assets/teamupnologo.png"; import { Link, useNavigate } from "react-router-dom"; @@ -6,32 +6,44 @@ import { Link, useNavigate } from "react-router-dom"; const Navbar = () => { const navigation = useNavigate(); const [toggle, setToggle] = useState(false); + const [scrolled, setScrolled] = useState(false); + + useEffect(() => { + const handleScroll = () => { + setScrolled(window.scrollY > 20); + }; + window.addEventListener("scroll", handleScroll); + return () => window.removeEventListener("scroll", handleScroll); + }, []); return ( -