From fd90edfce5d737563d82d38745cc1bd953d86187 Mon Sep 17 00:00:00 2001 From: Zeakeers <168440015+Zeakeers@users.noreply.github.com> Date: Thu, 8 May 2025 01:53:25 +0700 Subject: [PATCH] perubahan desain frontend --- frontend/src/App.js | 364 ++++++++++++---------- frontend/src/components/Footer.js | 57 ++-- frontend/src/components/Header.js | 117 +++++-- frontend/src/components/KategoriRating.js | 188 ++++++----- frontend/src/components/PopUp.js | 17 +- frontend/src/components/Tentang.js | 51 ++- frontend/src/pages/ListGame.js | 115 +++---- 7 files changed, 548 insertions(+), 361 deletions(-) diff --git a/frontend/src/App.js b/frontend/src/App.js index 882b1f8..93e910e 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -149,202 +149,236 @@ const App = () => { } }; return ( -
+
-
-
0 || rating ? 'bg-white rounded-lg shadow-md' : ''}`}> - {step === 0 && !rating && ( -

Rating Umur Game

- )} - {step > 0 && step <= questions.length && ( -
+ + {/* Hero Section */} +
+
+
0 || rating ? 'bg-white/95 backdrop-blur-sm rounded-2xl shadow-2xl' : ''}`}> + {step === 0 && !rating && ( +

+ Rating Umur Game +

+ )} + + {step > 0 && step <= questions.length && ( +
{step > 1 && ( +
- )} - {!rating && step === 0 && ( - <> -

Masukkan nama game:

- setGameName(e.target.value)} - className="border border-gray-600 bg-gray-100 p-2 w-full mt-2 focus:bg-gray-200 focus:border-black rounded mt-1" - /> - {suggestions.length > 0 && ( -
    - {suggestions.map((suggestion, index) => ( -
  • handleSelectGame(suggestion)} - > - {suggestion} -
  • - ))} -
- )} + )} + + {!rating && step === 0 && ( +
+

Masukkan nama game:

+
+ setGameName(e.target.value)} + className="w-full px-4 py-3 rounded-xl border-2 border-gray-300 focus:border-yellow-500 focus:ring-2 focus:ring-yellow-200 transition-all duration-300 bg-white/90 backdrop-blur-sm" + placeholder="Ketik nama game..." + /> + {suggestions.length > 0 && ( +
    + {suggestions.map((suggestion, index) => ( +
  • handleSelectGame(suggestion)} + > + {suggestion} +
  • + ))} +
+ )} +
- {/* Daftar 5 game terbaru */} - {latestGames.length > 0 && ( -
-

Game Terbaru:

-
+ + {latestGames.length > 0 && ( +
+

Game Terbaru:

+
{latestGames.map((game, index) => ( ))} {latestGames.length >= 4 && ( - + Selengkapnya )}
)} - - )} - {!rating && step > 0 && step <= questions.length && ( - <> -

{questions[step - 1]}

- {options.map((option) => ( - - ))} - - )} - {!rating && step > questions.length && ( - <> - {/* Menampilkan tabel hasil jawaban */} -
-

Hasil Jawaban Anda:

- - - - - - - - - {questions.map((question, index) => ( - - - - - ))} - -
PertanyaanJawaban
{question}{answers[index]}
-
- {/* Tombol kembali ke input game */} - - {/* Tombol untuk konfirmasi hasil */} - - - )} +
+ )} - {rating && ( - <> - {easterEggActive ? ( -

+ {!rating && step > 0 && step <= questions.length && ( +
+

+ {questions[step - 1]} +

+
+ {options.map((option) => ( + + ))} +
+
+ )} + + {!rating && step > questions.length && ( +
+

Hasil Jawaban Anda:

+
+ + + + + + + + + {questions.map((question, index) => ( + + + + + ))} + +
PertanyaanJawaban
{question}{answers[index]}
+
+
+ + +
+
+ )} + + {rating && ( +
+ {easterEggActive ? ( +
+

🎉 BISMILLAH LULUS 2025 DENGAN SEDIKIT REVISI 🎓

- ) : ( - <> -

- Game {gameName} memiliki rating - {rating} -

-

Penjelasan: {ratingDescriptions[rating]}

- - )} - - - - )} - - - {/* Pop-up konfirmasi pilihan jawaban */} - setIsPopUpOpen(false)} - onConfirm={confirmSelection} - selectedOption={selectedOption} - /> - - {/* Pop-up konfirmasi cek hasil */} - setIsConfirmPopupOpen(false)} - onConfirm={confirmSubmit} - selectedOption="Apakah Anda yakin ingin melihat hasil rating?" - /> -
-
-
- +
+ ) : ( +
+

+ Game {gameName} memiliki rating + {rating} +

+

+ Penjelasan: {ratingDescriptions[rating]} +

+
+ )} + +

+ )}
- -
+
+ +
+ +
+ + + +
+ + {/* Pop-ups */} + setIsPopUpOpen(false)} + onConfirm={confirmSelection} + selectedOption={selectedOption} + /> + + setIsConfirmPopupOpen(false)} + onConfirm={confirmSubmit} + selectedOption="Apakah Anda yakin ingin melihat hasil rating?" + />
); }; diff --git a/frontend/src/components/Footer.js b/frontend/src/components/Footer.js index 8d029ff..cdb3594 100644 --- a/frontend/src/components/Footer.js +++ b/frontend/src/components/Footer.js @@ -1,30 +1,35 @@ -import react from "react"; +import React from "react"; const Footer = () => { return ( -
-

© 2025 Rating Umur Game. All rights reserved.

-

- Developed by Dimas Adi -

- -
- ); - }; +
+
+
+

© 2025 Rating Umur Game. All rights reserved.

+

+ Developed by Dimas Adi +

+
+ +
+
+ ); +}; + export default Footer; \ No newline at end of file diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index 99af0a3..55907bd 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -1,46 +1,109 @@ -import react from "react"; +import { useState, useEffect } from "react"; const Header = ({ scrollToSection }) => { - const handleNavigation = (section) => { + const [isMenuOpen, setIsMenuOpen] = useState(false); + const [isVisible, setIsVisible] = useState(true); + const [lastScrollY, setLastScrollY] = useState(0); + + const handleNavigation = (section) => { + setIsMenuOpen(false); if (scrollToSection) { scrollToSection(section); } else { window.location.href = `/#${section}`; } }; + + useEffect(() => { + const controlNavbar = () => { + const currentScrollY = window.scrollY; + if (currentScrollY > lastScrollY) { + setIsVisible(false); + } else { + setIsVisible(true); + } + setLastScrollY(currentScrollY); + }; + + window.addEventListener('scroll', controlNavbar); + return () => { + window.removeEventListener('scroll', controlNavbar); + }; + }, [lastScrollY]); + return ( -
-

-
+ + {/* Desktop menu */} + -
- ); - }; - + +
+
+ + {/* Mobile menu */} +
+
+ + + +
+
+
+ ); +}; + export default Header; \ No newline at end of file diff --git a/frontend/src/components/KategoriRating.js b/frontend/src/components/KategoriRating.js index 01b60b4..2f62017 100644 --- a/frontend/src/components/KategoriRating.js +++ b/frontend/src/components/KategoriRating.js @@ -2,89 +2,133 @@ import React, { useState } from "react"; const KategoriRating = () => { const [currentIndex, setCurrentIndex] = useState(0); - const cards = [ - { imageUrl: "/images/SU.png", text: "Semua Umur - Dapat dimainkan oleh semua orang tanpa batasan konten." }, - { imageUrl: "/images/3+.png", text: "Usia 3 Tahun Keatas - Tidak ada konten dewasa, perjudian, atau interaksi online." }, - { imageUrl: "/images/7+.png", text: "Usia 7 Tahun Keatas - Ada unsur ringan seperti kekerasan kartun atau bahasa ringan." }, - { imageUrl: "/images/13+.png", text: "Usia 13 Tahun Keatas - Ada kekerasan moderat, simulasi perjudian, atau tema horor." }, - { imageUrl: "/images/18+.png", text: "Usia 18 Tahun Keatas - Mengandung konten dewasa, kekerasan realistis, atau humor kasar." } - ]; + const cards = [ + { imageUrl: "/images/SU.png", text: "Semua Umur - Dapat dimainkan oleh semua orang tanpa batasan konten." }, + { imageUrl: "/images/3+.png", text: "Usia 3 Tahun Keatas - Tidak ada konten dewasa, perjudian, atau interaksi online." }, + { imageUrl: "/images/7+.png", text: "Usia 7 Tahun Keatas - Ada unsur ringan seperti kekerasan kartun atau bahasa ringan." }, + { imageUrl: "/images/13+.png", text: "Usia 13 Tahun Keatas - Ada kekerasan moderat, simulasi perjudian, atau tema horor." }, + { imageUrl: "/images/18+.png", text: "Usia 18 Tahun Keatas - Mengandung konten dewasa, kekerasan realistis, atau humor kasar." } + ]; - const nextSlide = () => { - setCurrentIndex((prevIndex) => (prevIndex + 1) % cards.length); - }; + const nextSlide = () => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % cards.length); + }; - const prevSlide = () => { - setCurrentIndex((prevIndex) => (prevIndex - 1 + cards.length) % cards.length); - }; - return ( -
-
-
+ const prevSlide = () => { + setCurrentIndex((prevIndex) => (prevIndex - 1 + cards.length) % cards.length); + }; - {/* Konten utama */} -
- {/* Teks di sebelah kiri */} -
-

- Dalam Peraturan Menteri Komunikasi dan Informatika Nomor 2 Tahun 2024, - gim diklasifikasikan berdasarkan kelompok usia pengguna: 3+, 7+, 13+, dan 18+. - Setiap kategori ini mempertimbangkan jenis konten yang ditampilkan, seperti kekerasan, - bahasa, unsur horor, hingga interaksi daring. Semakin tinggi kelompok usia, - semakin kompleks pula konten yang diizinkan, namun tetap dalam batasan yang - tidak melanggar norma dan hukum yang berlaku. Klasifikasi ini bertujuan agar - setiap pengguna dapat memainkan gim yang sesuai dengan tingkat kedewasaan mereka, - serta membantu orang tua dalam mengawasi pilihan hiburan digital anak-anaknya. - -

-
+ return ( +
+
+
-
-
- {cards.slice(currentIndex, currentIndex + 2).map((card, index) => ( - - ))} + {/* Konten utama */} +
+
+

+ Kategori Rating +

+
+
+ +
+ {/* Teks di sebelah kiri */} +
+
+

+ Dalam Peraturan Menteri Komunikasi dan Informatika Nomor 2 Tahun 2024, + gim diklasifikasikan berdasarkan kelompok usia pengguna: 3+, 7+, 13+, dan 18+. + Setiap kategori ini mempertimbangkan jenis konten yang ditampilkan, seperti kekerasan, + bahasa, unsur horor, hingga interaksi daring. +

+

+ Semakin tinggi kelompok usia, semakin kompleks pula konten yang diizinkan, + namun tetap dalam batasan yang tidak melanggar norma dan hukum yang berlaku. + Klasifikasi ini bertujuan agar setiap pengguna dapat memainkan gim yang sesuai + dengan tingkat kedewasaan mereka, serta membantu orang tua dalam mengawasi + pilihan hiburan digital anak-anaknya. +

+
+
+ + {/* Cards di sebelah kanan */} +
+
+ {cards.slice(currentIndex, currentIndex + (window.innerWidth < 1024 ? 1 : 2)).map((card, index) => ( + + ))} +
+
+ + +
+
+
-
- - -
-
-
- - ); + ); }; const FlipCard = ({ imageUrl, text }) => { - const [flipped, setFlipped] = useState(false); + const [flipped, setFlipped] = useState(false); - return ( -
setFlipped(true)} - onMouseLeave={() => setFlipped(false)} - > -
- {/* Depan - Gambar */} -
- Gambar + return ( +
setFlipped(true)} + onMouseLeave={() => setFlipped(false)} + > +
+ {/* Depan - Gambar */} +
+ Rating +
+ {/* Belakang - Teks */} +
+

+ {text} +

+
+
- {/* Belakang - Teks */} -
-

{text}

-
-
-
- ); + ); }; export default KategoriRating; diff --git a/frontend/src/components/PopUp.js b/frontend/src/components/PopUp.js index 0fcfa2b..73c28cb 100644 --- a/frontend/src/components/PopUp.js +++ b/frontend/src/components/PopUp.js @@ -1,23 +1,26 @@ import React from "react"; - const PopUp = ({ isOpen, onClose, onConfirm, selectedOption }) => { if (!isOpen) return null; return ( -
-
-

Apakah Anda yakin memilih: {selectedOption}?

-
+
+
+

+ Apakah Anda yakin memilih: +
+ {selectedOption} +

+
diff --git a/frontend/src/components/Tentang.js b/frontend/src/components/Tentang.js index be13968..20ed740 100644 --- a/frontend/src/components/Tentang.js +++ b/frontend/src/components/Tentang.js @@ -1,13 +1,50 @@ -import react from "react"; +import React from "react"; const Tentang = () => { return ( -
-

Tentang

-

Klasifikasi gim itu penting, bukan untuk membatasi, tetapi agar semua orang terutama anak muda dapat bermain dengan aman dan sesuai usia. - Berdasarkan Peraturan Menteri Komunikasi dan Informatika Nomor 2 Tahun 2024, setiap gim yang beredar di Indonesia perlu melewati proses klasifikasi yang - mempertimbangkan konten dan nilai-nilai budaya kita. Di sini, kami mendukung langkah ini dengan semangat terbuka, agar para pengembang dan pemain sama-sama - tahu mana yang pas buat siapa. Soal seru-seruan, tetap jalan, tapi tetap bijak juga.

+
+
+
+

+ Tentang +

+
+
+ +
+

+ Klasifikasi gim itu penting, bukan untuk membatasi, tetapi agar semua orang terutama anak muda dapat bermain dengan aman dan sesuai usia. +

+ +

+ Berdasarkan Peraturan Menteri Komunikasi dan Informatika Nomor 2 Tahun 2024, setiap gim yang beredar di Indonesia perlu melewati proses klasifikasi yang + mempertimbangkan konten dan nilai-nilai budaya kita. +

+ +

+ Di sini, kami mendukung langkah ini dengan semangat terbuka, agar para pengembang dan pemain sama-sama + tahu mana yang pas buat siapa. Soal seru-seruan, tetap jalan, tapi tetap bijak juga. +

+
+ +
+
+
🏷️
+

Klasifikasi

+

Sistem penilaian yang tepat untuk setiap gim

+
+
+
🛡️
+

Keamanan

+

Melindungi pemain sesuai usia

+
+
+
🎮
+

Developer Game Indonesia

+

Membantu developer game Indonesia dalam menentukan rating umur pada game yang sedang dibuat.

+
+
+
); }; diff --git a/frontend/src/pages/ListGame.js b/frontend/src/pages/ListGame.js index 67706c1..c171161 100644 --- a/frontend/src/pages/ListGame.js +++ b/frontend/src/pages/ListGame.js @@ -68,68 +68,69 @@ const ListGames = () => { }; return ( -
+
-
-

Daftar Game

+ {/* Add top padding to prevent header overlap */} +
+

Daftar Game

- {/* Grid untuk filter di kiri, search + list game di kanan */} -
- {/* Bagian 1: Filter Rating */} - + {/* Responsive grid: filter on top on mobile, left on desktop */} +
+ {/* Filter */} + - {/* Bagian 2: Daftar Game */} -
- {/* Bagian 3: Search Form */} -
- -
+ {/* Main Content */} +
+ {/* Search Bar */} +
+ +
- {/* Card List Game */} -
- {filteredGames.length > 0 ? ( - filteredGames.map((game, index) => { - const ratingInfo = ratingDescriptions[game.rating] || {}; - return ( -
-

{game.name}

-

- Rating: {ratingInfo.label} -

-

- {ratingInfo.description} -

-
- ); - }) - ) : ( -

Tidak ada game yang sesuai.

- )} -
-
-
+ {/* Game Cards */} +
+ {filteredGames.length > 0 ? ( + filteredGames.map((game, index) => { + const ratingInfo = ratingDescriptions[game.rating] || {}; + return ( +
+

{game.name}

+

+ Rating: {ratingInfo.label} +

+

+ {ratingInfo.description} +

+
+ ); + }) + ) : ( +

Tidak ada game yang sesuai.

+ )} +
+ +