Migrate from PHP to independent backend #107
Merged
maxime.batista
merged 15 commits from remove-php
into master
1 year ago
Loading…
Reference in new issue
There is no content yet.
Delete Branch 'remove-php'
Deleting a branch is permanent. It CANNOT be undone. Continue?
Due to the second part of the SAE which requires the backend to be a standalone web service, this pull request removes all the php code, and let the front communicate with the server using 100% of API calls.
API standardisation.
The current front uses the dotnet implementation of the web service. You can change the endpoint in the .env file :
Error handling
Any errors returned by the backend MUST follow the given simple rule :
One json object is returned, with the keys corresponding to the type of the error, and the value corresponding to its message, for example :
Authentication
Ask a token
Use
/auth/token
route to generate a token based on the given credentials :If the credentials are invalid, the API must return a 401 (unauthorized) code.
Make a request that needs auth
For requests that needs to be authenticated, the token must be passed within the
Authorization
Header.Token prolongation
For each request that needs to be authenticated, they'll return a new token with an elongated expiration date.
The new token is sent by the server and stored in the response header ̀Next-Authorization
, its expiration date is stored in the response header named
Next-Authorization-Expiration-Date`.module.exports = {
Choose either a
.eslintrc.cjs
or a.eslintrc.js
file.# How to run the project on my local computer
1. Use phpstorm to run a local php server:
Is it still relevant?
}
"name": "iqball_web",
"version": "0.1.0",
"private": true,
Add
"type": "module"
in new applications.import { BrowserRouter, Outlet, Route, Routes } from "react-router-dom"
import loadable from "@loadable/component"
You don't need an external library to lazy load.
Just use the
lazy={() => import()}
attribute with react-router.a29192c0d4
to423cb03c4b
1 year ago423cb03c4b
to2478b4a403
1 year ago2478b4a403
tod25fe38a7c
1 year agod25fe38a7c
to9eca18dc0b
1 year ago9eca18dc0b
to78f8c35b03
1 year ago78f8c35b03
to5de0ba76f1
1 year ago5de0ba76f1
to15ace155e2
1 year ago15ace155e2
tof42303f363
1 year agof42303f363
to7c3c9340ab
1 year ago7c3c9340ab
to97caca533b
1 year ago97caca533b
to98aef3fd3a
1 year ago98aef3fd3a
to07f89c8ed6
1 year ago07f89c8ed6
toc5b59e5c1f
1 year agoc5b59e5c1f
to56bcf3e4b2
1 year ago56bcf3e4b2
to8fc8aa6917
1 year agoextends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
You are missing rules from the previous file:
-
- BASE="/IQBall/$DRONE_BRANCH/public" OUTPUT=/outputs /root/.local/bin/moshell ci/build_react.msh
- sed -Ei "s/VITE_BASE=/VITE_BASE=\\/${DRONE_BRANCH}/g" .env
- npm run build -- --base=/$DRONE_BRANCH
You're defining the base url two times, just use the
--base
argument and you are good to go.import.meta.env.BASE_URL
will cover your eventual needs to have the current path.import { getSession, saveSession, Session } from "./api/session.ts"
export function redirect(url: string) {
location.pathname = BASE + url
Note that you are bypassing client-side routing here by using the browser API.
}
export default function EditorPage({ guestMode }: EditorPageProps) {
const [tactic, setTactic] = useState<TacticDto>()
// import AccountSvg from "../assets/account.svg?react"
import { BASE } from "../Constants"
import { getSession } from "../api/session.ts"
import { fetchAPIGet, redirect } from "../Fetcher.ts"
import { FormEvent, useRef, useState } from "react"
import { BASE } from "../Constants.ts"
import { fetchAPI, redirect } from "../Fetcher.ts"
const emailRef = useRef<HTMLInputElement>(null)
const passwordRef = useRef<HTMLInputElement>(null)
e.preventDefault()
const email = emailRef.current!.value
const password = passwordRef.current!.value
{
type: "Non autorisé",
messages: [
"L'adresse email ou le mot de passe sont invalide.",
// import "../style/visualizer.css"
// import Court from "../assets/court/full_court.svg"
//
// // export default function Visualizer({ id, name }: { id: number; name: string }) {
Double comments? Wahh
import AccountSvg from "../../assets/account.svg?react"
import "../../style/template/header.css"
import { useEffect, useState } from "react"
import { fetchAPIGet, redirect } from "../../Fetcher.ts"
include: "**/*.svg?react"
})
]
include: "**/*.svg?react",
That is already the default.
Do not forget to run Prettier.
"warn",
{ allowConstantExport: true },
],
},
New plugins add new configuration settings.
return (
<div>
<h1>{target.pathname} NOT FOUND !</h1>
<button onClick={() => (location.pathname = BASE + "/")}>
To go the extra mile, I would argue that if your button behaves like a link, then it is a
a
element, not abutton
. keywboard navigation and accessibility, you know it's a long story... (A link can perfectly have a button style while still being ana
element)<a href={BASE + "/register"} className="inscr">
Vous n'avez pas de compte ?
</a>
<Link>
<a href={BASE + "/login"} className="inscr">
Vous avez déjà un compte ?
</a>
6eacfc1ae2
to12daaeaf5c
1 year ago12daaeaf5c
to66ddf4cb00
1 year ago66ddf4cb00
to5b13fbfbc8
1 year ago5b13fbfbc8
toedfc5368f9
1 year agoedfc5368f9
to1d1ac1e088
1 year agobf5de96871
tob322ffecaa
1 year ago30c3e1e7b4
to19ee432c35
1 year ago19ee432c35
tobc313ae1da
1 year agobc313ae1da
to26127798e4
1 year ago26127798e4
toee24f57fce
1 year agoee24f57fce
todefd53c9bc
1 year agomaster
Just default it to master?
No because we could start a new features that would also needs to requires modification of the API, and we won't apply thoses changes directly on the implementation's master branch
Yeah, but the whole reason why this file is here is because of the multi repo architecture. Yes, you will need some way to link a branch between the two repositories, but it seems strange to have a file dedicated to that. I tend to prefer not to have random files outside the CI files. They are not related to the code.
export default function App() {
return (
<div id="app">
<BrowserRouter basename={BASE}>
This router uses lazy components, without any
Suspense
element to show when loading. Your current workaround is to wrap all navigation changes in a transition block. It becomes very verbose.Either:
<Suspense>
if (response.status === 401) startTransition(() => {
// if unauthorized
navigate("/login")
return
This
return
doesn't have any effect since it's the last statement in the transition.const username = usernameField.current!.value
const password = passwordField.current!.value
const confirmpassword = confirmpasswordField.current!.value
const email = emailField.current!.value
a1ac1fe72c
into master 1 year agoReviewers
a1ac1fe72c
.