Funcionnal custom checkboxes, fixed small card component and added the ability to launch both backend and frontend at once
This commit is contained in:
parent
f8bf646565
commit
ca96f57fb8
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules/
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wf-radio-backend",
|
||||
"version": "1.0.0",
|
||||
"version": "Alpha 1",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "wf-radio-frontend",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "Alpha 1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
|
1
frontend/src/assets/checkmark.svg
Normal file
1
frontend/src/assets/checkmark.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M382-221.91 135.91-468l75.66-75.65L382-373.22l366.43-366.43L824.09-664 382-221.91Z"/></svg>
|
After Width: | Height: | Size: 207 B |
|
@ -1,8 +1,10 @@
|
|||
//TODO made by AI
|
||||
import { h } from 'preact';
|
||||
import { useState } from 'preact/hooks';
|
||||
import styles from './checkbox.module.css';
|
||||
|
||||
// Assets
|
||||
import Checkmark from '../../assets/checkmark.svg'
|
||||
|
||||
function Checkbox({ id, name, value, checked: initialChecked, onChange, label }) {
|
||||
const [isChecked, setIsChecked] = useState(initialChecked || false);
|
||||
|
||||
|
@ -24,11 +26,8 @@ function Checkbox({ id, name, value, checked: initialChecked, onChange, label })
|
|||
onChange={handleChange}
|
||||
className={styles.nativeCheckbox} // Hide this element
|
||||
/>
|
||||
<label htmlFor={id} className={styles.checkbox}>
|
||||
{/* This div will be our custom visual checkbox */}
|
||||
<div className={styles.checkmark}>
|
||||
{isChecked && <span>✓</span>} {/* Checkmark icon */}
|
||||
</div>
|
||||
<label htmlFor={id} className={styles.customCheckbox}>
|
||||
{isChecked && <img src={Checkmark} className={styles.checkmark} ></img>}
|
||||
{label && <span className={styles.label}>{label}</span>}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -1,51 +1,66 @@
|
|||
/*TODO made by AI */
|
||||
.checkboxContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none; /* Prevent text selection on click */
|
||||
margin: 1.5em .5em;
|
||||
/* width: 100%; */
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.nativeCheckbox {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
height: 0;
|
||||
width: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.customCheckbox {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 20px; /* Adjust size as needed */
|
||||
height: 20px;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px; /* Optional rounded corners */
|
||||
position: relative;
|
||||
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
min-height: 1em;
|
||||
min-width: 1em;
|
||||
|
||||
width: 1.7em; /* Adjust size as needed */
|
||||
height: 1.7em;
|
||||
|
||||
background-color: transparent;
|
||||
border: #eaeaea .1rem solid;
|
||||
border-radius: .2em;
|
||||
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
|
||||
transition: 200ms;
|
||||
}
|
||||
|
||||
.customCheckbox:hover input ~ .checkmark {
|
||||
background-color: #ddd;
|
||||
.customCheckbox:hover {
|
||||
background-color: #eaeaea20;
|
||||
}
|
||||
|
||||
.nativeCheckbox:checked ~ .customCheckbox {
|
||||
background-color: #2196F3; /* Active color */
|
||||
border: 1px solid #2196F3;
|
||||
|
||||
background-color: #353be5;
|
||||
border: #353be5 .1rem solid;
|
||||
/* border-radius: .3em; */
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: white; /* Checkmark color */
|
||||
font-size: 16px; /* Adjust checkmark size */
|
||||
.nativeCheckbox:checked ~ .customCheckbox:hover {
|
||||
border: #6b70f7 .1rem solid;
|
||||
filter: drop-shadow(#353be580 0 0 .7em);
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-left: 8px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
margin-left: 2.5em;
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
transform: scale(1.2);
|
||||
height: 100%;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
.rowCard {
|
||||
|
||||
height: 7rem;
|
||||
min-height: 7rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
background-color: #1a1a1a;
|
||||
|
|
|
@ -22,6 +22,8 @@ function SmallCard({item, variant, href}) {
|
|||
const item_page = "/mods/" + item.name;
|
||||
return (
|
||||
<a className={styles.Card} href={href}>
|
||||
<img src={Banner} className={styles.banner}></img>
|
||||
<img src={Thumbnail} className={styles.thumbnail}></img>
|
||||
<div className={styles.CardText}>
|
||||
{item.display_name}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
.emptyCard {
|
||||
height: 100%;
|
||||
width: 22em;
|
||||
min-width: 22em;
|
||||
min-height: 13rem;
|
||||
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
|
@ -25,27 +28,66 @@
|
|||
}
|
||||
|
||||
.Card {
|
||||
height: 100%;
|
||||
width: 22em;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
background-color: #141414;
|
||||
position: relative;
|
||||
|
||||
height: 100%;
|
||||
min-width: 22em;
|
||||
min-height: 13rem;
|
||||
|
||||
background-color: #101010;
|
||||
border: #3a3a3a .1rem solid;
|
||||
border-radius: 1rem;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.CardText {
|
||||
|
||||
padding: 1em;
|
||||
width: 100%;
|
||||
margin-left: 7rem;
|
||||
margin-top: .2rem;
|
||||
|
||||
color: #9a9a9a;
|
||||
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
color: #eaeaea;
|
||||
/* font-weight: 600; */
|
||||
font-size: 1.3rem;
|
||||
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
|
||||
.banner {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
|
||||
filter: brightness(50%);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
|
||||
.thumbnail {
|
||||
position: absolute;
|
||||
left: 1rem;
|
||||
top: 25%;
|
||||
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
|
||||
padding: .5rem;
|
||||
|
||||
background-color: #101010;
|
||||
border: #3a3a3a .1rem solid;
|
||||
border-radius: 1rem;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
|
||||
.Card:hover {
|
||||
filter: drop-shadow(#353be515 0 0 1em);
|
||||
transform: scale(1.01);
|
||||
border-color: #6b70f7;
|
||||
}
|
|
@ -92,7 +92,7 @@ function DashboardPage() {
|
|||
return (
|
||||
<>
|
||||
{base_page}
|
||||
<div class='container'>
|
||||
<div class={styles.container}>
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
</>
|
||||
|
@ -103,7 +103,7 @@ function DashboardPage() {
|
|||
return (
|
||||
<>
|
||||
{base_page}
|
||||
<div class='container'>
|
||||
<div class={styles.container}>
|
||||
<p>Error: {creations_error}</p>
|
||||
</div>
|
||||
</>
|
||||
|
@ -113,7 +113,7 @@ function DashboardPage() {
|
|||
return (
|
||||
<>
|
||||
{base_page}
|
||||
<div class='container'>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.category}>
|
||||
<p className={styles.title}>
|
||||
Favorites
|
||||
|
@ -149,6 +149,8 @@ function DashboardPage() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 2rem"/>
|
||||
</div>
|
||||
<div className={styles.toolbar}>
|
||||
<div className={styles.toolbarRightItems}>
|
||||
<Button
|
||||
|
@ -159,7 +161,6 @@ function DashboardPage() {
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,12 +9,16 @@ import { listMods } from '../services/mods';
|
|||
import FiltersPanel from '../components/Filters/panel'
|
||||
import SearchBar from '../components/Fields/search';
|
||||
|
||||
// Assets
|
||||
import '../styles/filters_bar.css'
|
||||
|
||||
// Images
|
||||
import logo from '../assets/logo.png'
|
||||
|
||||
// Styles
|
||||
// Components
|
||||
import GridCard from '../components/Cards/grid';
|
||||
import RowCard from '../components/Cards/row';
|
||||
import Checkbox from '../components/Buttons/checkbox';
|
||||
|
||||
|
||||
function ModsPage() {
|
||||
|
@ -67,7 +71,19 @@ function ModsPage() {
|
|||
</a>
|
||||
<FiltersPanel>
|
||||
<SearchBar onSearch={handleSearch} />
|
||||
|
||||
<div class='filterTitle'>
|
||||
Platform
|
||||
</div>
|
||||
<div class='filterOptions'>
|
||||
<Checkbox
|
||||
id='client'
|
||||
label='Client'
|
||||
/>
|
||||
<Checkbox
|
||||
id='server'
|
||||
label='Server'
|
||||
/>
|
||||
</div>
|
||||
</FiltersPanel>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -9,6 +9,7 @@ import { deleteUser } from '../services/users';
|
|||
|
||||
// Components
|
||||
import Button from '../components/Buttons/button';
|
||||
import Checkbox from '../components/Buttons/checkbox';
|
||||
|
||||
// Styles
|
||||
import styles from '../styles/settings.module.css'
|
||||
|
@ -97,16 +98,12 @@ function SettingsPage() {
|
|||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
Enable Notifications:
|
||||
<input
|
||||
type="checkbox"
|
||||
<Checkbox
|
||||
id='notifications'
|
||||
label='Enable Notifications'
|
||||
checked={notificationsEnabled}
|
||||
onChange={handleNotificationsChange}
|
||||
/>
|
||||
</label>
|
||||
</p>
|
||||
</>
|
||||
) :
|
||||
tab === 'user' ? (
|
||||
|
|
|
@ -129,6 +129,12 @@ h1 {
|
|||
/* border: #3a3a3a solid; */
|
||||
border-width: .1em;
|
||||
border-radius: .5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: .5rem;
|
||||
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.container {
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
.container {
|
||||
position: absolute;
|
||||
top: 11rem;
|
||||
right: 4rem;
|
||||
left: 22rem;
|
||||
bottom: 4rem;
|
||||
|
||||
padding: 3rem;
|
||||
padding-top: 2rem;
|
||||
|
||||
background-color: #1a1a1a;
|
||||
color: #eaeaea;
|
||||
|
||||
border: #3a3a3a solid;
|
||||
border-width: .1em;
|
||||
border-radius: .5rem;
|
||||
|
||||
overflow: scroll;
|
||||
|
||||
}
|
||||
|
||||
.category {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
@ -14,8 +35,10 @@
|
|||
|
||||
.tiles {
|
||||
|
||||
height: 13rem;
|
||||
margin-bottom: 3rem;
|
||||
height: 14rem;
|
||||
margin-bottom: 2rem;
|
||||
padding: 1rem;
|
||||
margin-right: -3rem;
|
||||
|
||||
overflow-x: scroll;
|
||||
overflow-y: visible;
|
||||
|
@ -26,20 +49,29 @@
|
|||
|
||||
.toolbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
right: 5rem;
|
||||
left: 23rem;
|
||||
bottom: 5rem;
|
||||
|
||||
height: 5rem;
|
||||
padding: .5rem;
|
||||
height: 3rem;
|
||||
min-width: 30rem;
|
||||
padding: 1rem;
|
||||
|
||||
background-color: #141414;
|
||||
border: #3a3a3a .1rem solid;
|
||||
border-radius: .5rem;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
/* background-color: #9a9a9a; */
|
||||
}
|
||||
|
||||
.toolbarRightItems {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
/* position: absolute; */
|
||||
/* right: 1rem; */
|
||||
/* bottom: 1rem; */
|
||||
margin-left: auto;
|
||||
|
||||
}
|
||||
.createButton {
|
||||
|
|
9
frontend/src/styles/filters_bar.css
Normal file
9
frontend/src/styles/filters_bar.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.filterTitle {
|
||||
font-weight: 600;
|
||||
font-size:1.3em;
|
||||
margin-top: 1.4em
|
||||
}
|
||||
|
||||
.filterOptions {
|
||||
font-size:0.9em;
|
||||
}
|
20
package.json
Normal file
20
package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "wf-radio",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start:frontend": "cd frontend && pnpm dev",
|
||||
"start:backend": "cd backend && pnpm start",
|
||||
"build:frontend": "cd frontend && pnpm build",
|
||||
"start:dev": "npm-run-all --parallel start:frontend start:backend",
|
||||
"start:prod": "npm-run-all --parallel build:frontend start:backend",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"packageManager": "pnpm@10.11.0",
|
||||
"devDependencies": {
|
||||
"npm-run-all": "^4.1.5"
|
||||
}
|
||||
}
|
1220
pnpm-lock.yaml
Normal file
1220
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue