diff --git a/index.html b/index.html index f4c043c..e1f3365 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Vite + React + Servii - Hebergement facile diff --git a/package.json b/package.json index 57ee456..70d12b1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "1.9.45", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite --host", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", diff --git a/src/App.jsx b/src/App.jsx index edea5c8..4f52c07 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -9,6 +9,10 @@ import { auth } from './service/firebase'; import styles from './App.module.scss'; import Loading from './pages/Loading/loading'; import NotFoundPage from './pages/NotFoundPage/NotFoundPage'; +import CreatePage from './pages/CreateServer/CreateServer'; +import Javapick from './pages/CreateServer/Javapick/java'; +import Modpack from './pages/CreateServer/modpack/modpack'; +import Bedrock from './pages/CreateServer/bedrock/bedrock'; const App = () => { const [user, setUser] = useState(null); @@ -33,7 +37,10 @@ const App = () => { : } /> : } /> - } /> + : } /> + : } /> + : } /> + : } /> : } /> } /> } /> diff --git a/src/assets/bedrock.png b/src/assets/bedrock.png new file mode 100644 index 0000000..e5b1cbf Binary files /dev/null and b/src/assets/bedrock.png differ diff --git a/src/assets/java.png b/src/assets/java.png new file mode 100644 index 0000000..35bb749 Binary files /dev/null and b/src/assets/java.png differ diff --git a/src/assets/moded.png b/src/assets/moded.png new file mode 100644 index 0000000..ab5c42d Binary files /dev/null and b/src/assets/moded.png differ diff --git a/src/components/CreateServer/CreateServer.jsx b/src/components/CreateServer/CreateServer.jsx index 865621d..8bfe9c5 100644 --- a/src/components/CreateServer/CreateServer.jsx +++ b/src/components/CreateServer/CreateServer.jsx @@ -133,39 +133,10 @@ const CreateServer = ({ user, onCreateServer, onSubdomainUpdate, onCancel, noSer ) : ( -
+
Création du serveur
- setServerName(validateInput(e.target.value))} - /> - -
Sélection de la version
- -
- {versions['paper'].map((version, index) => ( -
- {serverVersion === version ? : } - {version} -
- ))} -
-
- - -
+
Comment voulez vous jouer ?
+
dd
) ) diff --git a/src/components/CreateServer/CreateServer.module.scss b/src/components/CreateServer/CreateServer.module.scss index 1e91405..067dce3 100644 --- a/src/components/CreateServer/CreateServer.module.scss +++ b/src/components/CreateServer/CreateServer.module.scss @@ -9,14 +9,12 @@ .title { font-size: 2.5rem; - color: #F2F2F2; font-weight: 700; margin-bottom: 1.5rem; } .subtitle { font-size: 1.2rem; - color: #AAA6C3; font-weight: 300; text-align: center; margin-bottom: 2rem; @@ -66,7 +64,6 @@ .nsSubTitle { font-size: 1.8rem; - color: #AAA6C3; font-weight: 300; } @@ -93,15 +90,15 @@ background-color: #090325; } -.mainCardCreateServ { - margin-top: 5rem; +.GamesChoice { + margin-top: var(--navbar-height); + width: 50rem; + height: 10rem; + background-color: red; display: flex; justify-content: center; - align-items: start; + align-items: center; flex-direction: column; - background-color: #1D1836; - border-radius: 1rem; - padding: 2rem; } .mainCardSubdomain { @@ -114,7 +111,6 @@ .subtitle { font-size: 1.2rem; - color: #AAA6C3; font-weight: 600; text-align: start; margin-bottom: 1.5rem; diff --git a/src/components/navbar/Navbar.jsx b/src/components/navbar/Navbar.jsx index 104a13b..f7f9ee6 100644 --- a/src/components/navbar/Navbar.jsx +++ b/src/components/navbar/Navbar.jsx @@ -2,10 +2,16 @@ import { useState, useEffect, useRef } from 'react'; import { auth } from '../../service/firebase'; import styles from './Navbar.module.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faUser, faCog, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'; +import { faUser, faCog, faSignOutAlt, faArrowLeft } from '@fortawesome/free-solid-svg-icons'; import PropTypes from "prop-types"; -const Navbar = ({ user }) => { +const Navbar = ({ + user, + hasShadow = true, + showBackButton = false, + onBackClick, + backButtonText = "Retour au dashboard" +}) => { const [dropdownOpen, setDropdownOpen] = useState(false); const dropdownRef = useRef(null); @@ -34,31 +40,36 @@ const Navbar = ({ user }) => { }; }, []); - useEffect(() => { - }, [user]); - return ( -
+
+ {showBackButton && ( +
+ + {backButtonText} {} +
+ )} +
{user && user.photoURL ? ( Profile ) : ( -
A
+
A
)}
+ {dropdownOpen && (
{user && user.displayName}
- Informations + Informations
- Paramètres + Paramètres
- Se déconnecter + Se déconnecter
)} @@ -75,6 +86,10 @@ Navbar.propTypes = { photoURL: PropTypes.string, }), ]), + hasShadow: PropTypes.bool, + showBackButton: PropTypes.bool, + onBackClick: PropTypes.func, + backButtonText: PropTypes.string, }; export default Navbar; diff --git a/src/components/navbar/Navbar.module.scss b/src/components/navbar/Navbar.module.scss index 0ae7cfc..8b7965a 100644 --- a/src/components/navbar/Navbar.module.scss +++ b/src/components/navbar/Navbar.module.scss @@ -2,15 +2,19 @@ display: flex; justify-content: flex-end; align-items: center; - padding: 0.833rem 1.667rem; + padding: 0.65rem 1.6rem; background-color: var(--navbar-background-color); color: var(--navbar-color); - box-shadow: 0 0.167rem 0.333rem rgba(0, 0, 0, 0.1); position: fixed; top: 0; width: 100%; z-index: 1000; height: var(--navbar-height); + transition: box-shadow 0.3s; +} + +.shadow { + box-shadow: 0 0.01rem 0.2rem rgba(0, 0, 0, 0.1); } .profileSection { @@ -30,26 +34,26 @@ .defaultProfilePic { background-color: #ccc; - color: #fff; + color: #fff; font-size: 1.5rem; } .dropdownMenu { position: absolute; - top: 4rem; - right: 4rem; + top: 4rem; + right: 4rem; background-color: #050816; - box-shadow: 0 0.167rem 0.833rem rgba(0, 0, 0, 0.15); - border-radius: 0.8rem; + box-shadow: 0 0.167rem 0.833rem rgba(0, 0, 0, 0.15); + border-radius: 0.8rem; overflow: hidden; z-index: 1001; - width: 20rem; + width: 20rem; border: .1rem solid #444444; font-size: 1.1rem; } .menuItem, .menuItemLogout { - padding: 1.25rem 2rem; + padding: 1.25rem 2rem; cursor: pointer; transition: background-color 0.3s, color 0.3s; font-weight: bold; @@ -68,3 +72,18 @@ margin-right: 1rem; font-size: 1.25rem; } + +.backButton { + display: flex; + align-items: center; + cursor: pointer; + font-weight: 400; + color: var(--primary-color); + margin-right: auto; + margin-left: 2rem; +} + +.backIcon { + margin-right: 0.5rem; + font-size: 1.5rem; +} diff --git a/src/components/serverCards/DefaultServerCard.jsx b/src/components/serverCards/DefaultServerCard.jsx index ec66a76..efb00e4 100644 --- a/src/components/serverCards/DefaultServerCard.jsx +++ b/src/components/serverCards/DefaultServerCard.jsx @@ -1,30 +1,23 @@ import { Link } from 'react-router-dom'; import styles from './DefaultServerCard.module.scss'; - -import bukkit from '../../assets/frameworks/bukkit.png'; +import paper from '../../assets/frameworks/paper.png'; import fabric from '../../assets/frameworks/fabric.png'; import forge from '../../assets/frameworks/forge.png'; -import paper from '../../assets/frameworks/paper.png'; -import spigot from '../../assets/frameworks/spigot.png'; -import vanilla from '../../assets/frameworks/vanilla.png'; import PropTypes from "prop-types"; +import { FaTrash } from 'react-icons/fa'; + +const ServerCard = ({ status, version, name, framework, onRunClick, onStopClick, onDeleteClick, countPlayers, maxPlayers, favoriteServer }) => { -// eslint-disable-next-line react/prop-types -const DefaultServerCard = ({ status, version, name, framework, onRunClick, onStopClick, onDeleteClick , countPlayers , maxPlayers}) => { const getFrameworkSource = () => { switch (framework) { - case "bukkit": - return bukkit; - case "fabric": + case 'frabric': return fabric; - case "forge": + case 'forge': return forge; - case "paper": - return paper; - case "spigot": - return spigot; + case 'bedrock': + return paper; default: - return vanilla; + return paper; } }; @@ -57,9 +50,9 @@ const DefaultServerCard = ({ status, version, name, framework, onRunClick, onSto return ( + to={`/server/${name}/options`} + className={favoriteServer ? styles.favoriteserverCard : styles.serverCard} + state={{ status }}>
{`${name} @@ -68,36 +61,58 @@ const DefaultServerCard = ({ status, version, name, framework, onRunClick, onSto
Version: {version}
-
- {status === false ? " " : countPlayers + "/" + maxPlayers + " joueurs"} -
{status === false ? ( - + ) : ( - + )}
- +
+ {status ? `${countPlayers}/${maxPlayers} joueurs` : " "} +
+ ); - }; -DefaultServerCard.propTypes = { - key: PropTypes.string, +ServerCard.propTypes = { status: PropTypes.bool, - version: PropTypes.string, - name: PropTypes.string, + version: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, framework: PropTypes.string, onRunClick: PropTypes.func.isRequired, onStopClick: PropTypes.func.isRequired, onDeleteClick: PropTypes.func.isRequired, countPlayers: PropTypes.number, - subdomain: PropTypes.string, + maxPlayers: PropTypes.number.isRequired, + favoriteServer: PropTypes.bool, }; -export default DefaultServerCard; +ServerCard.defaultProps = { + framework: 'default', + status: false, + countPlayers: 0, + favoriteServer: false, +}; + +export default ServerCard; diff --git a/src/components/serverCards/DefaultServerCard.module.scss b/src/components/serverCards/DefaultServerCard.module.scss index 1889809..8f6ef1b 100644 --- a/src/components/serverCards/DefaultServerCard.module.scss +++ b/src/components/serverCards/DefaultServerCard.module.scss @@ -2,16 +2,62 @@ display: flex; flex-direction: column; justify-content: space-between; - align-items: flex-start; - width: 35.5rem; + align-items: center; + width: 20rem; padding: 2rem; - border: 0.2rem solid var(--card-border-color); + border: 0.1rem solid black; border-radius: 0.8rem; - background-color: var(--card-bg-color); - color: var(--text-color); margin-bottom: 1.5rem; cursor: pointer; text-decoration: none; + color: black; + background: rgba(255, 255, 255, 0.2); + border-radius: 1rem; + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(5px); + border: 1px solid rgba(255, 255, 255, 0.3); + position: relative; +} + +.favoriteserverCard{ + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + width: 38.5rem; + padding: 3rem 0rem 3rem 3rem; + border: 0.1rem solid black; + border-radius: 0.8rem; + margin-bottom: 3rem; + cursor: pointer; + text-decoration: none; + color: black; + background: rgba(255, 255, 255, 0.2); + border-radius: 1rem; + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(5px); + border: 1px solid rgba(255, 255, 255, 0.3); + position: relative; +} + +.serverCard:hover{ + box-shadow: + 0 4px 30px rgba(0, 0, 0, 0.1), + 2px 2px 10px rgba(255, 0, 0, 0.2), + -2px -2px 15px rgba(0, 255, 0, 0.2), + 4px -4px 20px rgba(0, 0, 255, 0.2); box-shadow: + 0 +} + +.favoriteserverCard:hover{ + box-shadow: + 0 4px 30px rgba(0, 0, 0, 0.1), + 2px 2px 10px rgba(255, 0, 0, 0.2), + -2px -2px 15px rgba(0, 255, 0, 0.2), + 4px -4px 20px rgba(0, 0, 255, 0.2); box-shadow: + 0 } .header { @@ -26,13 +72,13 @@ } .frameworkIcon { - width: 2.5rem; - height: 2.5rem; + width: 3rem; + height: 3rem; margin-right: 0.8rem; } .serverName { - font-size: 1.6rem; + font-size: 1.5rem; font-weight: bold; } @@ -46,6 +92,7 @@ font-size: 1.2rem; font-weight: bold; color: var(--status-color); + margin-right: 2rem; } .actions { @@ -56,8 +103,8 @@ } .startStopButton { - padding: 1rem 1.8rem; - border-radius: 0.6rem; + padding: 1rem 1.5rem; + border-radius: 0.5rem; border: none; color: white; cursor: pointer; @@ -80,16 +127,23 @@ background-color: #8d213ec1; } -.deleteButton { - background-color: #d9534f; - color: white; - border: none; - border-radius: 0.6rem; - padding: 0.6rem 1rem; +.trashIcon { + position: absolute; + top: 1rem; + right: 1rem; + font-size: 1.5rem; + opacity: 0; + transition: opacity 0.3s ease; cursor: pointer; - transition: background-color 0.3s ease; } -.deleteButton:hover { - background-color: #c9302c; +.serverCard:hover .trashIcon { + opacity: 1; } + +.favoriteserverCard:hover .trashIcon { + opacity: 1; +} + + + diff --git a/src/main.css b/src/main.css index 5ccd456..d1b4cd9 100644 --- a/src/main.css +++ b/src/main.css @@ -2,27 +2,21 @@ html { font-size: 12px; font-family: 'Poppins', sans-serif; + scroll-behavior: smooth; } :root { - --navbar-height: 5rem; - --navbar-background-color: #100D25; - --navbar-color: #fff; - --profile-pic-size: 3rem; - --logout-button-bg: #ff4b4b; - --logout-button-bg-hover: #ff1a1a; - --card-width: 80%; - --card-padding: 3.5rem; - --card-border-color: #343947; - --card-bg-color: #1D1836; - --main-bg-color: #050816; - --text-color: white; + --navbar-height: 4rem; + --navbar-background-color: #FFFF; + --profile-pic-size: 3.5rem; + --main-background-color: #FFFF; + + --card-bg-color: white; + --main-bg-color: white; --text-color-black: black; --input-bg-color: #44475a; --input-border-color: #6272a4; - --button-bg-color: #50fa7b; - --button-text-color: #282a36; - --button-bg-color-hover: #8be9fd; + } body { @@ -60,7 +54,7 @@ body { @media (min-width: 2000px) { html { - font-size: 20px; + font-size: 15px; } } diff --git a/src/pages/CreateServer/CreateServer.jsx b/src/pages/CreateServer/CreateServer.jsx new file mode 100644 index 0000000..ecbf540 --- /dev/null +++ b/src/pages/CreateServer/CreateServer.jsx @@ -0,0 +1,61 @@ +import styles from './CreateServer.module.scss'; +import PropTypes from "prop-types"; +import Navbar from '../../components/navbar/Navbar'; +import { useNavigate } from 'react-router-dom'; +import bedrockimg from '../../assets/bedrock.png'; +import modedimg from '../../assets/moded.png'; +import javaimg from '../../assets/java.png' + +const CreateServer = ({ user }) => { + const navigate = useNavigate(); + + + return ( +
+ navigate('/dashboard')} + /> + +
+
Création du serveur
+
De quelle façon voulez-vous jouer ?
+
+
navigate('/CreateServer/java')}> + +
Java Edition
+
Découvrez la version classique de Minecraft sur PC, avec un large éventail de mises à jour et de fonctionnalités, couvrant plus de vingt versions !
+ +
+
navigate('/CreateServer/bedrock')}> + +
Mini-jeu
+
Plongez dans Minecraft avec des cartes personnalisées et des règles uniques, en solo ou avec vos amis.
+ +
+
navigate('/CreateServer/modpack')}> + +
Minecraft Modé
+
Explorez la version modifiée de Minecraft sur PC, avec des modpacks riches et variés, contenant plus de 200 mods pour une expérience de jeu personnalisée.
+ +
+
+
+
+ ); +}; + +CreateServer.propTypes = { + user: PropTypes.oneOfType([ + PropTypes.shape({ + uid: PropTypes.string.isRequired, + displayName: PropTypes.string, + email: PropTypes.string, + photoURL: PropTypes.string, + }), + ]), +}; + +export default CreateServer; diff --git a/src/pages/CreateServer/CreateServer.module.scss b/src/pages/CreateServer/CreateServer.module.scss new file mode 100644 index 0000000..2a8ae86 --- /dev/null +++ b/src/pages/CreateServer/CreateServer.module.scss @@ -0,0 +1,87 @@ +.Container { + display: flex; + justify-content: center; + align-items: center; +} + +.GamesChoice { + margin-top: 20rem; + width: 50rem; + height: 10rem; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.title { + font-size: 2rem; + margin-top: 5rem; + font-weight: 500; +} + +.subtitle { + font-size: 1.25rem; + margin-top: 1rem; +} + +.GamesContainer { + margin-top: 2.5rem; + display: flex; + justify-content: center; + align-items: center; + flex-wrap: row; +} + +.GameCard { + margin: 2.5rem; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + border-radius: .4rem; + cursor: pointer; + padding: 1rem 1rem 2rem 1rem; +} + +.GameCard:hover { + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; +} + +img { + border-radius: .4rem; +} + +.GameButton { + margin-top: 1rem; + padding: .5rem 1rem; + border-radius: .4rem; + background-color: #2f2f2f; + color: white; + cursor: pointer; + + visibility: hidden; + opacity: 0; +} + +.GameCard:hover .GameButton { + visibility: visible; + opacity: 1; + +} + +.Gamesubtitle { + font-size: 1.2rem; + margin-top: .75rem; +} + +.Gamedescription { + font-size: 1rem; + margin-top: .7rem; + text-align: center; +} + +.imgCard{ + width: 22rem; + height: auto; +} \ No newline at end of file diff --git a/src/pages/CreateServer/Javapick/java.jsx b/src/pages/CreateServer/Javapick/java.jsx new file mode 100644 index 0000000..52dbc07 --- /dev/null +++ b/src/pages/CreateServer/Javapick/java.jsx @@ -0,0 +1,123 @@ +import { useState, useEffect, useRef } from 'react'; +import { GoTag, GoCheck } from "react-icons/go"; +import { useNavigate } from 'react-router-dom'; +import styles from './java.module.scss'; +import PropTypes from "prop-types"; +import Navbar from '../../../components/navbar/Navbar'; +import serviiApi from "../../../service/api.tsx"; + +const Javapick = ({ user }) => { + const [serverName, setServerName] = useState(''); + const [serverVersion, setServerVersion] = useState(''); + const [isButtonVisible, setIsButtonVisible] = useState(false); + const navigate = useNavigate(); + const isValidServerName = serverName.length > 2; + + const buttonRef = useRef(null); + + const validateInput = (input) => { + return input.replace(/[^a-zA-Z]/g, ''); + }; + + const handleCreateServer = async () => { + try { + const framework = 'paper'; + await serviiApi.serverCreate(serverName, serverVersion, framework); + navigate('/Dashboard'); + } catch (error) { + console.error('Error creating server:', error); + } + }; + + const versions = { + paper: [ + "1.20.6", "1.20.5", "1.20.4", "1.20.2", "1.20.1", "1.20", + "1.19.4", "1.19.3", "1.19.2", "1.19", "1.18.2", "1.18.1", + "1.17.1", "1.16.5", "1.16.4", "1.16.3", "1.16.2", "1.16.1", + "1.15.2", "1.15.1", "1.14.4", "1.14.3", "1.14.2", "1.14.1", + "1.13.2", "1.13.1", "1.12.2", "1.11.2", "1.10.2", "1.9.4" + ].sort((a, b) => b.localeCompare(a, undefined, { numeric: true })) + }; + + useEffect(() => { + if (isValidServerName && serverVersion) { + setIsButtonVisible(true); + buttonRef.current?.scrollIntoView({ behavior: 'smooth' }); + } else { + setIsButtonVisible(false); + } + }, [isValidServerName, serverVersion]); + + const VersionChoice = (version) => { + return () => { + setServerVersion(version); + if (isValidServerName) { + setTimeout(() => { + buttonRef.current?.scrollIntoView({ behavior: 'smooth' }); + }, 150); + } + }; + }; + + return ( +
+ navigate('/CreateServer')} + /> +
+
+

Saisissez le nom du serveur

+ setServerName(validateInput(e.target.value))} + className={`${styles.serverInput} ${isValidServerName ? styles.validInput : ''}`} + /> +
+ + {isValidServerName && ( +
+

Choisissez la version du serveur

+
+ {versions['paper'].map((version, index) => ( +
+ {serverVersion === version ? : } + {version} +
+ ))} +
+
+ )} + + {isButtonVisible && ( + + )} +
+
+ ); +}; + +Javapick.propTypes = { + user: PropTypes.shape({ + uid: PropTypes.string.isRequired, + email: PropTypes.string, + photoURL: PropTypes.string, + }), +}; + +export default Javapick; diff --git a/src/pages/CreateServer/Javapick/java.module.scss b/src/pages/CreateServer/Javapick/java.module.scss new file mode 100644 index 0000000..e256bab --- /dev/null +++ b/src/pages/CreateServer/Javapick/java.module.scss @@ -0,0 +1,128 @@ +.Container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + transition: all 0.5s ease-in-out; + + h2{ + font-weight: 400; + } + } + + .hey { + margin-top: 8rem; + display: flex; + flex-direction: column; + align-items: center; + transition: all 0.5s ease-in-out; + } + + .inputContainer { + margin-bottom: 3rem; + display: flex; + flex-direction: column; + align-items: center; + transition: all 0.5s ease-in-out; + transform: translateX(0); + } + + .inputContainer.inputValid { + align-items: self-end; + transform: translateX(-115%); + transition: transform 0.5s ease-in-out; + } + + .serverInput { + width: 100%; + max-width: 500px; + padding: 15px; + font-size: 1.5rem; + border: 2px solid #ccc; + border-radius: 10px; + box-shadow: 0 0 0 0 rgba(0, 170, 255, 0.5); + transition: border-color 0.4s ease, box-shadow 0.4s ease, transform 0.5s ease-in-out; + + &:focus { + outline: none; + border-color: #00aaff; + box-shadow: 0 0 10px 2px rgba(0, 170, 255, 0.5); + } + } + + .validInput { + border-color: #198754; + box-shadow: 0 0 10px 2px rgba(25, 135, 84, 0.5); + transition: border-color 0.4s ease, box-shadow 0.4s ease; + } + + .ContainerVersion { + box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; + padding: 2rem; + border-radius: 0.4rem; + background-color: #fff; + margin-top: 3rem; + margin-bottom: 1.5rem; + opacity: 0; + transform: translateY(-3rem); + transition: opacity 0.4s ease, transform 0.4s ease; + } + + .ContainerVersion.visible { + opacity: 1; + transform: translateY(0); + } + + .VersionContainer { + display: grid; + grid-template-columns: repeat(8, 1fr); + justify-items: center; + align-items: center; + width: 100%; + gap: 1rem; + } + + .VersionCard { + height: 4rem; + width: 8rem; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + margin-bottom: 1rem; + border-radius: 0.3rem; + background-color: #f0f0f0; + color: #333; + transition: background-color 0.3s ease, transform 0.3s ease; + } + + .VersionCard:hover { + cursor: pointer; + background-color: #00aaff; + color: #fff; + } + + .selectedVersion { + background-color: #198754; + color: #fff; + box-shadow: 0 0 10px 2px rgba(25, 135, 84, 0.5); + } + + .createButton { + padding: 1rem 4rem; + margin-top: 4rem; + margin-bottom: 4rem; + background-color: #198754; + color: #fff; + border: none; + border-radius: 5px; + font-size: 1.5rem; + cursor: pointer; + transition: background-color 0.3s ease, transform 0.3s ease; + align-self: flex-start; +} + +.createButton:hover { + background-color: #145a32; + transform: scale(1.05); +} diff --git a/src/pages/CreateServer/bedrock/bedrock.jsx b/src/pages/CreateServer/bedrock/bedrock.jsx new file mode 100644 index 0000000..36110f2 --- /dev/null +++ b/src/pages/CreateServer/bedrock/bedrock.jsx @@ -0,0 +1,38 @@ +import styles from './bedrock.module.scss'; +import PropTypes from "prop-types"; +import Navbar from '../../../components/navbar/Navbar'; +import { useNavigate } from 'react-router-dom'; + + +const Bedrock = ({ user }) => { + const navigate = useNavigate(); + + + return ( +
+ navigate('/CreateServer')} + /> +
+

Prochainement disponible

+
+
+ ); +}; + +Bedrock.propTypes = { + user: PropTypes.oneOfType([ + PropTypes.shape({ + uid: PropTypes.string.isRequired, + displayName: PropTypes.string, + email: PropTypes.string, + photoURL: PropTypes.string, + }), + ]), +}; + +export default Bedrock; diff --git a/src/pages/CreateServer/bedrock/bedrock.module.scss b/src/pages/CreateServer/bedrock/bedrock.module.scss new file mode 100644 index 0000000..5ec5e9c --- /dev/null +++ b/src/pages/CreateServer/bedrock/bedrock.module.scss @@ -0,0 +1,3 @@ +.hey{ + margin-top: 8em; +} \ No newline at end of file diff --git a/src/pages/CreateServer/modpack/modpack.jsx b/src/pages/CreateServer/modpack/modpack.jsx new file mode 100644 index 0000000..57e8345 --- /dev/null +++ b/src/pages/CreateServer/modpack/modpack.jsx @@ -0,0 +1,38 @@ +import styles from './modpack.module.scss'; +import PropTypes from "prop-types"; +import Navbar from '../../../components/navbar/Navbar'; +import { useNavigate } from 'react-router-dom'; + + +const Modpack = ({ user }) => { + const navigate = useNavigate(); + + + return ( +
+ navigate('/CreateServer')} + /> +
+

Prochainement disponible

+
+
+ ); +}; + +Modpack.propTypes = { + user: PropTypes.oneOfType([ + PropTypes.shape({ + uid: PropTypes.string.isRequired, + displayName: PropTypes.string, + email: PropTypes.string, + photoURL: PropTypes.string, + }), + ]), +}; + +export default Modpack; diff --git a/src/pages/CreateServer/modpack/modpack.module.scss b/src/pages/CreateServer/modpack/modpack.module.scss new file mode 100644 index 0000000..5ec5e9c --- /dev/null +++ b/src/pages/CreateServer/modpack/modpack.module.scss @@ -0,0 +1,3 @@ +.hey{ + margin-top: 8em; +} \ No newline at end of file diff --git a/src/pages/DashboardPage/DashboardPage.jsx b/src/pages/DashboardPage/DashboardPage.jsx index 2526645..056b6d9 100644 --- a/src/pages/DashboardPage/DashboardPage.jsx +++ b/src/pages/DashboardPage/DashboardPage.jsx @@ -1,62 +1,48 @@ -import { useEffect, useState } from 'react'; -import DefaultServerCard from '../../components/serverCards/DefaultServerCard.jsx'; +import { useEffect, useState, useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; +import ServerCard from '../../components/serverCards/DefaultServerCard'; import Navbar from '../../components/navbar/Navbar'; -import styles from './DashboardPage.module.scss'; import Loading from '../Loading/loading'; -import CreateServer from '../../components/CreateServer/CreateServer'; import { getUserSubdomain } from "../../service/firebase"; import serviiApi from "../../service/api.tsx"; import PropTypes from "prop-types"; +import styles from './DashboardPage.module.scss'; const DashboardPage = ({ user }) => { + const navigate = useNavigate(); + const [servers, setServers] = useState([]); const [subdomain, setSubdomain] = useState(null); const [loading, setLoading] = useState(true); - const [showCreateServer, setShowCreateServer] = useState(false); + const [searchTerm, setSearchTerm] = useState(''); + const [newSubdomain, setNewSubdomain] = useState(''); - const loadServers = async () => { + const loadServers = useCallback(async () => { try { - const ApiResponse = await serviiApi.fetchServers(); - const data = ApiResponse.message; - const sortedServers = data.sort((a, b) => b.running - a.running); - setServers(sortedServers); - - if (user && user.uid) { + if (user?.uid) { const userSubdomain = await getUserSubdomain(user.uid); setSubdomain(userSubdomain || ''); - } else { - console.error('User or user.uid is undefined'); } } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } - }; + + const ApiResponse = await serviiApi.fetchServers(); + const data = ApiResponse.message; + const sortedServers = data.sort((a, b) => b.running - a.running); + setServers(sortedServers); + + + }, [user]); useEffect(() => { loadServers(); - }, []); + }, [loadServers]); - const handleCreateServer = async (serverName, serverVersion , framework) => { - try { - if (!serverName || !serverVersion) return; - await serviiApi.serverCreate(serverName, serverVersion, framework); - await loadServers(); - setShowCreateServer(false); - } catch (error) { - console.error('Error creating server:', error); - } - }; - - const handleCreateServerPage = () => { - setShowCreateServer(true); - }; - - const handleCancelCreateServer = () => { - setShowCreateServer(false); - }; + const handleCreateServer = () => navigate('/CreateServer'); const handleRunServer = async (serverName) => { try { @@ -87,10 +73,26 @@ const DashboardPage = ({ user }) => { const handleCopyAddress = () => { const address = `${subdomain}.servii.fr`; - navigator.clipboard.writeText(address).then(r => r) - + navigator.clipboard.writeText(address); }; + const handleSaveSubdomain = async () => { + try { + const response = await serviiApi.setSubdomain(newSubdomain); + if (response.success) { + setSubdomain(newSubdomain); + loadServers(); + } else { + console.error('Erreur lors de la création du sous-domaine'); + } + } catch (error) { + console.error('Erreur lors de la création du sous-domaine:', error); + } + }; + + const favoriteServer = servers[0] || null; + const serversWithoutFavorite = servers.filter(server => server !== favoriteServer); + if (loading) { return (
@@ -100,71 +102,125 @@ const DashboardPage = ({ user }) => { ); } + if (!subdomain) { + return ( +
+

+ Bienvenue, {user?.displayName || ' '} ! +

+

+ Le sous-domaine est le nom sous lequel vos amis et vous rejoignez le serveur. Choisissez-le bien, car il nest pas facilement modifiable ! +

+
+ setNewSubdomain(e.target.value)} + className={styles.subdomainInput} + onKeyPress={(e) => e.key === 'Enter' && handleSaveSubdomain()} + /> + +
+
+ ); + } + + + if (servers.length === 0) { + return ( +
+ +
+ +
+
+ ); + } + return (
- {showCreateServer ? ( - - ) : ( -
- {servers.length === 0 ? ( - +
+ Adresse de connexion à vos serveurs : + + {" " + subdomain}.servii.fr + +
+ +
+ setSearchTerm(e.target.value)} + className={styles.searchInput} /> - ) : ( -
-
- Adresse de connexion à vos serveurs : - - {" " + subdomain}.servii.fr - + +
+ +
+ {favoriteServer ? ( +
+ handleRunServer(favoriteServer.name)} + onStopClick={() => handleStopServer(favoriteServer.name)} + onDeleteClick={() => handleDeleteServer(favoriteServer.name)} + subdomain={subdomain} + favoriteServer={true} + />
- - {servers.map((server) => ( - handleRunServer(server.name)} - onStopClick={() => handleStopServer(server.name)} - onDeleteClick={() => handleDeleteServer(server.name)} - subdomain={subdomain} - /> - ))} -
- )} + ) : null} +
+ +
+ {serversWithoutFavorite.length > 0 ? ( + serversWithoutFavorite.filter(server => + server.name.toLowerCase().includes(searchTerm.toLowerCase()) + ).map((server) => ( + handleRunServer(server.name)} + onStopClick={() => handleStopServer(server.name)} + onDeleteClick={() => handleDeleteServer(server.name)} + subdomain={subdomain} + /> + )) + ) : null} +
- )}
); }; DashboardPage.propTypes = { - user: PropTypes.oneOfType([ - PropTypes.shape({ - uid: PropTypes.string.isRequired, - displayName: PropTypes.string, - email: PropTypes.string, - }), - ]), + user: PropTypes.shape({ + uid: PropTypes.string.isRequired, + displayName: PropTypes.string, + email: PropTypes.string, + }), }; export default DashboardPage; diff --git a/src/pages/DashboardPage/DashboardPage.module.scss b/src/pages/DashboardPage/DashboardPage.module.scss index bf8697a..0b2fc5a 100644 --- a/src/pages/DashboardPage/DashboardPage.module.scss +++ b/src/pages/DashboardPage/DashboardPage.module.scss @@ -2,54 +2,145 @@ html, body { margin: 0; padding: 0; font-family: 'Poppins', system-ui, Avenir, Helvetica, Arial, sans-serif; - background-color: var(--main-bg-color); + background-color: var(--main-background-color); } - .dashboardContainer { padding-top: var(--navbar-height); - background-color: var(--main-bg-color); display: flex; flex-direction: column; align-items: center; - color: var(--text-color); + background-color: var(--main-background-color); + color: black; +} + +.mainContent { + width: 90%; + padding: 2.5rem; + display: flex; + flex-direction: column; + align-items: center; +} + +.headerContainer { + display: flex; + justify-content: center; + width: 100%; + align-items: center; + margin-bottom: 2rem; +} + +.searchInput { + border: .2rem solid #ccc; + border-radius: 8px; + padding: .8rem 1rem; + font-size: 1.25rem; + width: 16rem; + flex: none; } .cardsContainer { - width: 50rem; - margin-top: 5rem; - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(10rem, 25rem)); gap: 1rem; - align-items: center; + width: 100%; + max-width: 60rem; + margin: 0 auto; + justify-items: center; justify-content: center; } -.iptitle{ - font-size: 1.5rem; - font-weight: 600; - color: var(--text-color); - font-style: italic; - margin-bottom: 1.5rem; -} -.iptitle span { + +.subdomain { color: violet; cursor: pointer; + text-decoration: none; } -.btncreate{ +.btnCreate { display: flex; - justify-content: center; - align-items: center; - background-color: #1D1836; - width: 40rem; - height: 5rem; - color: white; - border: solid 0.1rem #090325; - cursor: pointer; - font-size: 2rem; - font-weight: 900; - border-radius: 1rem; - margin-bottom: 3rem; -} \ No newline at end of file + justify-content: center; + align-items: center; + background-color: #2f2f2f; + border: none; + padding: .5rem 1rem; + cursor: pointer; + font-size: 1rem; + font-weight: 600; + border-radius: 0.5rem; + color: white; + transition: background-color 0.3s ease; + margin-left: 1rem; +} + +.plusIcon { + font-size: 2rem; + margin-right: 1rem; +} + +.AllserversTitle, .favoriteServerTitle, .iptitle { + font-size: 1.5rem; + font-weight: 500; + color: var(--text-color); + margin: 1rem 0; +} + +.welcomeContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: 4rem; + padding: 2rem; + background-color: #f7f7f7; + border-radius: 0.5rem; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); +} + +.welcomeMessage { + font-size: 2.5rem; + font-weight: 600; + color: #333; + margin-bottom: 1rem; +} + +.subdomainMessage { + font-size: 1.2rem; + color: #666; + margin-bottom: 2rem; + text-align: center; + max-width: 50rem; +} + +.subdomainInputContainer { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: .25rem; +} + +.subdomainInput { + padding: 0.75rem 1rem; + border-radius: 0.5rem; + border: 1px solid #ccc; + font-size: 1.25rem; + width: 20rem; +} + +.btnCreateSubdomain { + display: flex; + justify-content: center; + align-items: center; + background-color: #2f2f2f; + padding: .80rem 1rem; + cursor: pointer; + font-size: 1rem; + font-weight: 600; + border: none; + color: white; + transition: background-color 0.3s ease; + margin-left: 1rem; + border-radius: 0.5rem; +} diff --git a/src/pages/ServerDetails/ServerDetails.jsx b/src/pages/ServerDetails/ServerDetails.jsx index 93c8d73..99ca6b9 100644 --- a/src/pages/ServerDetails/ServerDetails.jsx +++ b/src/pages/ServerDetails/ServerDetails.jsx @@ -9,15 +9,14 @@ import FeatureSoon from './FeatureSoon'; import styles from './ServerDetails.module.scss'; import PropTypes from "prop-types"; import { FaCogs, FaUserFriends, FaGlobe, FaHistory, FaClipboardList, FaSave, FaLock } from 'react-icons/fa'; -import { TbArrowBackUp } from 'react-icons/tb'; import { FiChevronsLeft, FiChevronsRight } from "react-icons/fi"; import NotFoundPage from '../NotFoundPage/NotFoundPage'; -import { useLocation } from 'react-router-dom'; +import { useLocation,useNavigate} from 'react-router-dom'; const ServerDetails = ({ user }) => { const { serverName } = useParams(); const location = useLocation(); - + const navigate = useNavigate(); const initialStatus = location.state?.status ?? JSON.parse(localStorage.getItem('status')) ?? false; const [status, setStatus] = useState(initialStatus); const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); @@ -38,7 +37,7 @@ const ServerDetails = ({ user }) => { return ( <> - + navigate('/Dashboard')} />
@@ -87,12 +86,7 @@ const ServerDetails = ({ user }) => { className={({ isActive }) => isActive ? `${styles.menuItem} ${styles.active}` : styles.menuItem}> {!isSidebarCollapsed && 'Accès'} - - - {!isSidebarCollapsed && 'Dashboard'} - +
diff --git a/src/pages/ServerDetails/ServerDetails.module.scss b/src/pages/ServerDetails/ServerDetails.module.scss index 74b622c..9723e03 100644 --- a/src/pages/ServerDetails/ServerDetails.module.scss +++ b/src/pages/ServerDetails/ServerDetails.module.scss @@ -6,15 +6,15 @@ .sidebar { width: 20rem; - background-color: #100D25; + background-color: white; padding-left: 0rem; padding-right: 1rem; box-sizing: border-box; position: fixed; height: calc(100vh - var(--navbar-height)); top: var(--navbar-height); - color: white; transition: width 0.3s; + box-shadow: 0.125rem 0 0.3125rem rgba(0, 0, 0, 0.1); } .sidebar.collapsed { @@ -30,28 +30,24 @@ .menuItem { display: flex; + color:black; align-items: center; padding: 0.7rem 1rem; - margin: .8rem 0rem; + margin: .5rem 0rem; padding-right: 0rem; - font-size: 1.25rem; + font-size: 1.15rem; cursor: pointer; - color: #D1D5DB; text-decoration: none; width: 100%; &.active { - background-color: #1D1836; - color: white; + background-color: white; } } -.menuItem:hover { - color: white; -} .menuItem svg { margin-right: 1rem; - font-size: 1.8rem; + font-size: 1.25rem; } .toggleButton { @@ -59,8 +55,7 @@ align-items: center; justify-content: center; font-size: 2rem; - color: white; - background-color: #100D25; + background-color: white; border: none; cursor: pointer; transition: background-color 0.3s; diff --git a/src/pages/ServerHistory/ServerHistory.module.scss b/src/pages/ServerHistory/ServerHistory.module.scss index 0cdf934..6e5bb95 100644 --- a/src/pages/ServerHistory/ServerHistory.module.scss +++ b/src/pages/ServerHistory/ServerHistory.module.scss @@ -6,7 +6,7 @@ display: flex; flex-direction: row; gap: 1.5rem; - background-color: #1D1836; + background-color: white; color: black; margin-bottom: 1rem; padding: 2.5rem; @@ -23,8 +23,8 @@ border: 1px solid #ccc; padding: 1rem; border-radius: 4px; - background-color: #100D25; - color: white; + background-color: white; + color: black; border: .1rem solid #343947; } @@ -34,7 +34,7 @@ display: flex; align-items: center; gap: 0.5rem; - color: white; + color: black; } .filterContainer input[type="checkbox"] { @@ -49,6 +49,6 @@ display: block; text-align: center; font-size: 1.5rem; - color: white; + color: black; font-weight: bold; } diff --git a/src/pages/ServerProperties/ServerProperties.module.scss b/src/pages/ServerProperties/ServerProperties.module.scss index a4bb1f8..6c4cf3a 100644 --- a/src/pages/ServerProperties/ServerProperties.module.scss +++ b/src/pages/ServerProperties/ServerProperties.module.scss @@ -1,6 +1,6 @@ .serverDetailsContainer { padding-top: var(--navbar-height); - background-color: var(--main-bg-color); + background-color: white; display: flex; flex-direction: column; align-items: center; @@ -11,9 +11,8 @@ .details { padding: 2rem; - background-color: #100D25; + background-color: white; width: 50rem; - box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.2); border-radius: 0.5rem; border: 0.1rem solid #343947; box-sizing: border-box; @@ -40,7 +39,7 @@ font-weight: 600; margin-bottom: 0.5rem; font-size: 1rem; - color: #EAEAEA; + color: black; } input, @@ -48,10 +47,10 @@ width: 15rem; max-width: 20rem; padding: 0.7rem; - background-color: #2C2C44; + background-color: white; border: 0.1rem solid #44476A; border-radius: 0.5rem; - color: #EAEAEA; + color: black; font-size: 1rem; box-sizing: border-box; transition: border-color 0.3s ease, box-shadow 0.3s ease; @@ -87,7 +86,7 @@ cursor: pointer; transition: background-color 0.3s ease, transform 0.3s ease; font-size: 1.1rem; - background-color: #1D1836; + background-color: black; @@ -104,7 +103,7 @@ .details h1 { font-size: 1.75rem; margin-bottom: 2rem; - color: #FFF; + color: black; text-align: center; }