generated from lucien/actix-react-template
Compare commits
No commits in common. "main" and "main_page" have entirely different histories.
19 changed files with 42 additions and 289 deletions
|
@ -12,9 +12,7 @@ pub fn init() -> sqlite::Result<()> {
|
||||||
"CREATE TABLE IF NOT EXISTS articles (
|
"CREATE TABLE IF NOT EXISTS articles (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
auteur TEXT,
|
subTitle TEXT,
|
||||||
edited_at DATE_FORMAT('now', '%YYYY-%mm-%dd'),
|
|
||||||
published_at DATE_FORMAT('now', '%YYYY-%mm-%dd'),
|
|
||||||
content TEXT NOT NULL
|
content TEXT NOT NULL
|
||||||
)",
|
)",
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod create_db;
|
mod create_db;
|
||||||
use create_db::init;
|
use create_db::init;
|
||||||
|
|
||||||
use actix_web::{App, web, HttpServer, get, Responder, HttpResponse, http::header::ContentType};
|
use actix_web::{App, HttpServer, get, Responder, HttpResponse, http::header::ContentType};
|
||||||
use actix_files::Files;
|
use actix_files::Files;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlite::{Connection, State};
|
use sqlite::{Connection, State};
|
||||||
|
@ -11,9 +11,9 @@ use serde::{Serialize, Deserialize};
|
||||||
struct Article {
|
struct Article {
|
||||||
id: i64,
|
id: i64,
|
||||||
title: String,
|
title: String,
|
||||||
auteur: String,
|
auteur: Option<String>,
|
||||||
edited_at: String,
|
edited_at: Option<String>,
|
||||||
published_at: String,
|
published_at: Option<String>,
|
||||||
content: String,
|
content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,13 +31,13 @@ async fn get_articles() -> impl Responder {
|
||||||
while let State::Row = stmt.next().unwrap() {
|
while let State::Row = stmt.next().unwrap() {
|
||||||
let id = stmt.read::<i64, _>(0).unwrap();
|
let id = stmt.read::<i64, _>(0).unwrap();
|
||||||
let title = stmt.read::<String, _>(1).unwrap();
|
let title = stmt.read::<String, _>(1).unwrap();
|
||||||
let content = stmt.read::<String, _>(5).unwrap();
|
let content = stmt.read::<String, _>(3).unwrap();
|
||||||
articles.push(Article {
|
articles.push(Article {
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
auteur: "".to_string(),
|
auteur: None,
|
||||||
edited_at: "".to_string(),
|
edited_at: None,
|
||||||
published_at: "".to_string(),
|
published_at: None,
|
||||||
content
|
content
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -45,54 +45,6 @@ async fn get_articles() -> impl Responder {
|
||||||
HttpResponse::Ok().json(articles)
|
HttpResponse::Ok().json(articles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[get("/api/articles/{id}")]
|
|
||||||
async fn get_article(path: web::Path<i64>) -> impl Responder {
|
|
||||||
let id = path.into_inner();
|
|
||||||
|
|
||||||
// Open the database connection
|
|
||||||
let conn = match Connection::open("./data/data.db") {
|
|
||||||
Ok(conn) => conn,
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Failed to connect to database: {}", err);
|
|
||||||
return HttpResponse::InternalServerError().body("Failed to connect to database");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fetch the article from the database
|
|
||||||
match fetch_article_by_id(&conn, id) {
|
|
||||||
Ok(Some(article)) => HttpResponse::Ok().json(article),
|
|
||||||
Ok(None) => HttpResponse::NotFound().body(format!("Article with ID {} not found", id)),
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Database query error: {}", err);
|
|
||||||
HttpResponse::InternalServerError().body("Database query failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetches an article by its ID from the database.
|
|
||||||
fn fetch_article_by_id(conn: &Connection, id: i64) -> Result<Option<Article>, sqlite::Error> {
|
|
||||||
let mut stmt = conn.prepare(
|
|
||||||
"SELECT id, title, auteur, edited_at, published_at, content
|
|
||||||
FROM articles WHERE id = ?1"
|
|
||||||
)?;
|
|
||||||
stmt.bind((1, id))?;
|
|
||||||
|
|
||||||
let mut article = None;
|
|
||||||
while let State::Row = stmt.next()? {
|
|
||||||
article = Some(Article {
|
|
||||||
id: stmt.read::<i64, _>(0)?,
|
|
||||||
title: stmt.read::<String, _>(1)?,
|
|
||||||
auteur: stmt.read::<String, _>(2)?,
|
|
||||||
edited_at: stmt.read::<String, _>(3)?,
|
|
||||||
published_at: stmt.read::<String, _>(4)?,
|
|
||||||
content: stmt.read::<String, _>(5)?,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(article)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/api")]
|
#[get("/api")]
|
||||||
async fn api() -> impl Responder {
|
async fn api() -> impl Responder {
|
||||||
let value = json!({
|
let value = json!({
|
||||||
|
@ -120,10 +72,7 @@ async fn main() -> Result<(), std::io::Error> {
|
||||||
.service(hello)
|
.service(hello)
|
||||||
.service(get_articles)
|
.service(get_articles)
|
||||||
.service(api)
|
.service(api)
|
||||||
.service(get_article)
|
|
||||||
.service(Files::new("/", "public").index_file("index.html"))
|
.service(Files::new("/", "public").index_file("index.html"))
|
||||||
.service(Files::new("/game", "public").index_file("index.html"))
|
|
||||||
.service(Files::new("/chaos", "public").index_file("index.html"))
|
|
||||||
})
|
})
|
||||||
.bind(("0.0.0.0", 2486))?
|
.bind(("0.0.0.0", 2486))?
|
||||||
.run()
|
.run()
|
||||||
|
|
|
@ -3,22 +3,10 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: dockerfile
|
dockerfile: dockerfile
|
||||||
network: host
|
container_name: web
|
||||||
container_name: nuitdelinfo
|
|
||||||
restart: always
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
volumes:
|
volumes:
|
||||||
- ./back/data:/app/data
|
- ./back/data:/app/data
|
||||||
networks:
|
|
||||||
- traefik
|
|
||||||
labels:
|
|
||||||
- "traefik.enable=true"
|
|
||||||
- "traefik.http.routers.nuitdelinfo.rule=Host(`nuitdelinfo.leizour.fr`)"
|
|
||||||
- "traefik.http.routers.nuitdelinfo.entrypoints=websecure"
|
|
||||||
- "traefik.http.routers.nuitdelinfo.tls=true"
|
|
||||||
- "traefik.http.routers.nuitdelinfo.tls.certresolver=myresolver"
|
|
||||||
- "traefik.http.services.nuitdelinfo.loadbalancer.server.port=2486"
|
|
||||||
|
|
||||||
networks:
|
|
||||||
traefik:
|
|
||||||
external: true
|
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@ RUN cargo build --release
|
||||||
|
|
||||||
FROM debian:bookworm-slim
|
FROM debian:bookworm-slim
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apt update && apt install -y libsqlite3-0
|
RUN apt-get update & apt-get install -y extra-runtime-dependencies & rm -rf /var/lib/apt/lists/*
|
||||||
COPY --from=front /app/dist /app/public
|
COPY --from=front /app/dist /app/public
|
||||||
COPY --from=back /app/target/release/back /app/back
|
COPY --from=back /app/target/release/back /app/back
|
||||||
EXPOSE 2486
|
EXPOSE 8080
|
||||||
CMD ["/app/back"]
|
CMD ["/app/back"]
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router": "^7.0.2",
|
"react-router": "^7.0.2",
|
||||||
|
"react-router-dom": "^6.2.1",
|
||||||
"three": "^0.171.0",
|
"three": "^0.171.0",
|
||||||
"three-stdlib": "^2.34.0",
|
"three-stdlib": "^2.34.0"
|
||||||
"react-router-dom": "^6.2.1"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.15.0",
|
"@eslint/js": "^9.15.0",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import React from 'react'
|
||||||
import { LineBasicMaterial, Line, Group } from 'three'
|
import { LineBasicMaterial, Line, Group } from 'three'
|
||||||
|
import { useFrame } from '@react-three/fiber'
|
||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
|
|
||||||
export default function Axes() {
|
export default function Axes() {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
import { Group, Mesh, MeshStandardMaterial, BufferGeometry } from 'three'
|
||||||
import { useGLTF } from '@react-three/drei'
|
import { useGLTF } from '@react-three/drei'
|
||||||
|
|
||||||
export default function Character() {
|
export default function Character() {
|
||||||
// import glb file
|
// import glb file
|
||||||
|
|
||||||
// load the glb file in "/models/BASEmodel.glb"
|
// load the glb file in "/models/BASEmodel.glb"
|
||||||
const { scene } = useGLTF('/models/man.glb')
|
const { nodes, materials, scene } = useGLTF('/models/man.glb')
|
||||||
|
|
||||||
// rotate the character
|
// rotate the character
|
||||||
scene.rotation.x = -Math.PI / 2
|
scene.rotation.x = -Math.PI / 2
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
import { Group } from 'three'
|
import { Group } from 'three'
|
||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { Group } from 'three'
|
||||||
import * as THREE from 'three'
|
import * as THREE from 'three'
|
||||||
|
|
||||||
interface MarkerProps {
|
interface MarkerProps {
|
||||||
position: number[],
|
position: [number, number, number],
|
||||||
color: string,
|
color: string,
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Marker({ position, color, onClick }: MarkerProps) {
|
export default function Marker({ position, color, onClick }: MarkerProps) {
|
||||||
|
|
||||||
const [positionState, setPositionState] = React.useState(new THREE.Vector3(...position))
|
const [positionState, setPositionState] = React.useState(position)
|
||||||
|
|
||||||
// Return the marker object
|
// Return the marker object
|
||||||
// return <primitive object={marker} />
|
// return <primitive object={marker} />
|
||||||
return (
|
return (
|
||||||
<mesh position={positionState} rotation={[Math.PI,0,0]} onClick={onClick} onPointerOver={() => setPositionState(positionState.clone().setZ(positionState.z + 0.1))} onPointerOut={() => setPositionState(new THREE.Vector3(...position))}>
|
<mesh position={positionState} rotation={[Math.PI,0,0]} onClick={onClick} onPointerOver={(e) => setPositionState([positionState[0], positionState[1], positionState[2] + 0.1])} onPointerOut={(e) => setPositionState(position)}>
|
||||||
<coneGeometry args={[0.15, 0.6, 6]} />
|
<coneGeometry args={[0.15, 0.6, 6]} />
|
||||||
<meshStandardMaterial color={color} side={THREE.DoubleSide} />
|
<meshStandardMaterial color={color} side={THREE.DoubleSide} />
|
||||||
</mesh>
|
</mesh>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { Water, WaterOptions } from 'three/examples/jsm/objects/Water.js';
|
import { Water, WaterOptions } from 'three/examples/jsm/objects/Water.js';
|
||||||
|
import { WaterMesh, WaterMeshOptions } from 'three/examples/jsm/objects/Water2Mesh.js';
|
||||||
|
|
||||||
const Ocean: React.FC = () => {
|
const Ocean: React.FC = () => {
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode, MouseEventHandler } from 'react';
|
||||||
|
|
||||||
interface ButtonProps {
|
interface ButtonProps {
|
||||||
color: 'primary' | 'secondary';
|
color: 'primary' | 'secondary';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import Button from "./Button";
|
||||||
|
import ButtonLink from "./ButtonLink";
|
||||||
import NavBar from "./NavBar";
|
import NavBar from "./NavBar";
|
||||||
import { Link } from "react-router";
|
|
||||||
|
|
||||||
export default function FstSection () {
|
export default function FstSection () {
|
||||||
return (
|
return (
|
||||||
|
@ -32,55 +32,8 @@ export default function FstSection () {
|
||||||
|
|
||||||
>Help us to save our oceans</h1><br />
|
>Help us to save our oceans</h1><br />
|
||||||
<div style={{display:"flex", justifyContent: "center", gap: "20px"}}>
|
<div style={{display:"flex", justifyContent: "center", gap: "20px"}}>
|
||||||
{/* <Button color="primary" children={"Aller au jeu"} url="/game" />
|
<Button color="primary" children={"Aller au jeu"} url="/game" />
|
||||||
<Button color="secondary" children={"Lire les articles"} url="/" /> */}
|
<Button color="secondary" children={"Lire les articles"} url="/" />
|
||||||
<Link to="/game" style={{
|
|
||||||
backgroundColor: 'var(--color-yellow)',
|
|
||||||
borderRadius: '8px',
|
|
||||||
borderWidth: '0',
|
|
||||||
color: 'var(--color-black)',
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'inline-block',
|
|
||||||
fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '500',
|
|
||||||
lineHeight: '20px',
|
|
||||||
listStyle: 'none',
|
|
||||||
margin: '0',
|
|
||||||
padding: '10px 12px',
|
|
||||||
textAlign: 'center',
|
|
||||||
transition: 'all 200ms',
|
|
||||||
verticalAlign: 'baseline',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
userSelect: 'none',
|
|
||||||
WebkitUserSelect: 'none',
|
|
||||||
touchAction: 'manipulation',
|
|
||||||
textDecoration: 'none',
|
|
||||||
}}>Aller au jeu</Link>
|
|
||||||
<Link to="/articles" style={{
|
|
||||||
backgroundColor: 'var(--color-darkblue)',
|
|
||||||
borderRadius: '8px',
|
|
||||||
borderWidth: '0',
|
|
||||||
color: 'var(--color-white)',
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'inline-block',
|
|
||||||
fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: '500',
|
|
||||||
lineHeight: '20px',
|
|
||||||
listStyle: 'none',
|
|
||||||
margin: '0',
|
|
||||||
padding: '10px 12px',
|
|
||||||
textAlign: 'center',
|
|
||||||
transition: 'all 200ms',
|
|
||||||
verticalAlign: 'baseline',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
userSelect: 'none',
|
|
||||||
WebkitUserSelect: 'none',
|
|
||||||
touchAction: 'manipulation',
|
|
||||||
textDecoration: 'none',
|
|
||||||
}}>Lire les articles</Link>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { Link } from 'react-router';
|
import LogoButton from '../components/LogoButton.tsx'
|
||||||
|
import ClickableLink from './ClickableLink.tsx';
|
||||||
import RoundButton from './RoundButton.tsx';
|
import RoundButton from './RoundButton.tsx';
|
||||||
|
|
||||||
export default function NavBar(){
|
export default function NavBar(){
|
||||||
|
@ -6,15 +7,13 @@ export default function NavBar(){
|
||||||
<nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0.5em 1em"}}>
|
<nav style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "0.5em 1em"}}>
|
||||||
<div style={{ display : "flex", alignItems: "center", flexDirection: "row"}}>
|
<div style={{ display : "flex", alignItems: "center", flexDirection: "row"}}>
|
||||||
{/* <LogoButton url="/" logo = "https://archlinux.org/static/hetzner_logo.41114a37d25f.png"/> */}
|
{/* <LogoButton url="/" logo = "https://archlinux.org/static/hetzner_logo.41114a37d25f.png"/> */}
|
||||||
<span className="material-symbols-outlined"
|
<span class="material-symbols-outlined"
|
||||||
style={{fontSize: "4em", color: "white", margin: "0.5em"}}>sailing</span>
|
style={{fontSize: "4em", color: "white", margin: "0.5em"}}>sailing</span>
|
||||||
<Link to="/" style={{ textDecoration: "none", color: "white", fontSize: "1.5em", margin: "0.5em", fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif'}}>Home</Link>
|
<ClickableLink url="/" text = "Accueil" />
|
||||||
<Link to="/game" style={{ textDecoration: "none", color: "white", fontSize: "1.5em", margin: "0.5em", fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif'}}>Game</Link>
|
<ClickableLink url="/game" text = "Jeu" />
|
||||||
<Link to="/articles" style={{ textDecoration: "none", color: "white", fontSize: "1.5em", margin: "0.5em", fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif'}}>Articles</Link>
|
|
||||||
<Link to="/chaos" style={{ textDecoration: "none", color: "white", fontSize: "1.5em", margin: "0.5em", fontFamily: '"Haas Grot Text R Web", "Helvetica Neue", Helvetica, Arial, sans-serif'}}>Le Chaos</Link>
|
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display : "flex", alignItems: "center", flexDirection: "row"}}>
|
<div style={{ display : "flex", alignItems: "center", flexDirection: "row"}}>
|
||||||
<RoundButton url="https://www.apple.com/macos/macos-sequoia/" bgcolor="var(--color-white)" text="?"/>
|
<RoundButton url="https://archlinux.org" bgcolor="var(--color-white)" text="?"/>
|
||||||
</div>
|
</div>
|
||||||
</nav>);
|
</nav>);
|
||||||
}
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
//import { useState } from "react";
|
|
||||||
|
|
||||||
interface MonInputProps {
|
|
||||||
text: string;
|
|
||||||
new_focus: () => void;
|
|
||||||
police: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function MonInput({text, new_focus, police}: MonInputProps) {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<input readOnly value={text} onFocus={new_focus} style={{fontFamily: police,width:1000}}></input>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
|
|
||||||
interface MonButtonProps {
|
|
||||||
letter: string;
|
|
||||||
changetext: (arg0: string) => void;
|
|
||||||
sizeFrontw: number;
|
|
||||||
sizeFronth: number;
|
|
||||||
rdmFront: () => void;
|
|
||||||
color: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default function MonButton({letter,changetext,sizeFrontw,sizeFronth,rdmFront,color}: MonButtonProps) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function clicked() {rdmFront();
|
|
||||||
changetext(letter)}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<button className="key" onClick={clicked} style={{width:sizeFrontw,height:sizeFronth,background:color}}>{letter}</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
#keys {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto 1fr;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.key {
|
|
||||||
font-size: 10px;
|
|
||||||
border: solid black;
|
|
||||||
}
|
|
|
@ -2,8 +2,6 @@ import { BrowserRouter, Route, Routes } from "react-router";
|
||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import MainPage from "./pages/MainPage.tsx";
|
import MainPage from "./pages/MainPage.tsx";
|
||||||
import GamePage from "./pages/GamePage.tsx";
|
import GamePage from "./pages/GamePage.tsx";
|
||||||
import ChaosPage from "./pages/ChaosPage.tsx";
|
|
||||||
|
|
||||||
import ArticlePage from "./pages/ArticlePage.tsx";
|
import ArticlePage from "./pages/ArticlePage.tsx";
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
|
@ -14,7 +12,6 @@ createRoot(document.getElementById('root')!).render(
|
||||||
<Route path="/" element={<MainPage />} />
|
<Route path="/" element={<MainPage />} />
|
||||||
// Game page
|
// Game page
|
||||||
<Route path="/game" element={<GamePage />} />
|
<Route path="/game" element={<GamePage />} />
|
||||||
<Route path="/chaos" element={<ChaosPage />} />
|
|
||||||
// Article page (dynamic route)
|
// Article page (dynamic route)
|
||||||
<Route path="/article/:id" element={<ArticlePage />} />
|
<Route path="/article/:id" element={<ArticlePage />} />
|
||||||
// Not found
|
// Not found
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import MonButton from "../components/chaos/monButton";
|
|
||||||
import MonInput from "../components/chaos/MonInput";
|
|
||||||
import "../components/chaos/style.css"
|
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
|
|
||||||
export default function ChaosPage(){
|
|
||||||
|
|
||||||
const [array_letter,setArray_letter]=useState(["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"," ","!"]);
|
|
||||||
|
|
||||||
const [sizeFrontw,setSizeFrontw] = useState(16)
|
|
||||||
const [sizeFronth,setSizeFronth] = useState(20)
|
|
||||||
const [color,setColor] = useState("#ffffff")
|
|
||||||
|
|
||||||
function randomFront(){setSizeFronth(Math.floor(Math.random() * (1000)));
|
|
||||||
setSizeFrontw(Math.floor(Math.random() * (1000)));
|
|
||||||
setColor(`#${Math.floor(Math.random() * 16777215).toString(16)}`)}
|
|
||||||
|
|
||||||
function shuffleArray(arr: string[]) {
|
|
||||||
for (let i = arr.length - 1; i > 0; i--) {
|
|
||||||
const j = Math.floor(Math.random() * (i + 1)); // Choisir un index aléatoire
|
|
||||||
[arr[i], arr[j]] = [arr[j], arr[i]]; // Échanger les éléments
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// console.log(shuffledArray); // Affiche un tableau mélangé
|
|
||||||
|
|
||||||
|
|
||||||
const [entry1,setEntry1] = useState("")
|
|
||||||
function E1(ent:string) {
|
|
||||||
setEntry1(entry1+ent);
|
|
||||||
}
|
|
||||||
const [connarddefocus,setFocus] = useState(()=>E1)
|
|
||||||
|
|
||||||
const [entry2,setEntry2] = useState("")
|
|
||||||
function E2(ent:string) {
|
|
||||||
setEntry2(entry2+ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeFocus(E: (ent:string)=>void) {
|
|
||||||
setArray_letter(shuffleArray(array_letter));
|
|
||||||
setFocus(()=>E);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [entry3,setEntry3] = useState("")
|
|
||||||
function E3(ent:string) {
|
|
||||||
setEntry3(entry3+ent);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [tel,setTel] = useState(0)
|
|
||||||
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
<h1>Chaos Page</h1>
|
|
||||||
<p>Quel est votre nom ?</p>
|
|
||||||
<MonInput text={entry1} new_focus={()=>changeFocus(E1)} police={""}/>
|
|
||||||
<p>Quel adjectif désigne le mieux Xi Junpin ?</p>
|
|
||||||
<MonInput text={entry2} new_focus={()=>changeFocus(E2)} police={""}/>
|
|
||||||
<p>Combien font 1+1 ?</p>
|
|
||||||
<MonInput text={entry3} new_focus={()=>changeFocus(E3)} police={"Wingdings"}/>
|
|
||||||
<div id = "keys">
|
|
||||||
{array_letter.map((letter) => {return <MonButton
|
|
||||||
letter={letter}
|
|
||||||
changetext={connarddefocus}
|
|
||||||
sizeFrontw={sizeFrontw}
|
|
||||||
sizeFronth={sizeFronth}
|
|
||||||
rdmFront={randomFront}
|
|
||||||
color={color}/> })}
|
|
||||||
</div>
|
|
||||||
<fieldset>
|
|
||||||
<legend>Formulaire super mega bien</legend>
|
|
||||||
<input type="text" placeholder="nom"/>
|
|
||||||
<input type="text" placeholder="prenom"/>
|
|
||||||
<input type="text" placeholder="email"/>
|
|
||||||
<input type="text" placeholder="mdp"/>
|
|
||||||
<input type="text" placeholder="mdp2"/>
|
|
||||||
<label htmlFor="phone">phone : {tel}</label>
|
|
||||||
<input type="range" min="0" max="9999999999" step="1" name="phone" id="phone" value={tel} onChange={(e)=>setTel(parseInt(e.target.value))}/>
|
|
||||||
<input type="submit" value="envoyer"/>
|
|
||||||
</fieldset>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { Canvas } from "@react-three/fiber";
|
import { Canvas } from "@react-three/fiber";
|
||||||
import { OrbitControls, PerspectiveCamera, Sky } from "@react-three/drei";
|
import { OrbitControls, PerspectiveCamera, Sky } from "@react-three/drei";
|
||||||
import { useEffect, useState } from "react";
|
import * as THREE from "three";
|
||||||
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import Ocean from "../components/3d/Ocean";
|
import Ocean from "../components/3d/Ocean";
|
||||||
|
import Axes from "../components/3d/Axes";
|
||||||
import Character from "../components/3d/Character";
|
import Character from "../components/3d/Character";
|
||||||
import Floor from "../components/3d/Floor";
|
import Floor from "../components/3d/Floor";
|
||||||
import Marker from "../components/3d/Marker";
|
import Marker from "../components/3d/Marker";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue