mirror of
https://git.rezel.net/LudoTech/traque.git
synced 2026-02-09 10:20:16 +01:00
fixed problems for depployment
This commit is contained in:
@@ -1,22 +1,18 @@
|
|||||||
services:
|
services:
|
||||||
front:
|
front:
|
||||||
build: ./traque-front
|
build: ./traque-front
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
reverse_proxy:
|
||||||
|
build: ./proxy
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:443"
|
||||||
environment:
|
volumes:
|
||||||
- NEXT_PUBLIC_SOCKET_HOST = 'quentinrsl.com'
|
- ./traque-back/ssl:/etc/nginx/ssl:ro
|
||||||
- NEXT_PUBLIC_SOCKET_PORT = 3001
|
restart: always
|
||||||
|
|
||||||
back:
|
back:
|
||||||
build: ./traque-back
|
build: ./traque-back
|
||||||
ports:
|
ports:
|
||||||
- "3001:3001"
|
- "3001:3001"
|
||||||
environment:
|
restart: always
|
||||||
- HOST = 'quentinrsl.com'
|
|
||||||
- PORT = 3001
|
|
||||||
- SSL_KEY = "/etc/letsencrypt/live/quentinrsl.com/privkey.pem"
|
|
||||||
- SSL_CERT = "/etc/letsencrypt/live/quentinrsl.com/cert.pem"
|
|
||||||
- ADMIN_PASSWORD = 'admin'
|
|
||||||
- MAX_PENALTIES = 3
|
|
||||||
- ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES = 10
|
|
||||||
- ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES = 10
|
|
||||||
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "traque",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
8
proxy/Dockerfile
Normal file
8
proxy/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# nginx/Dockerfile
|
||||||
|
|
||||||
|
FROM nginx:1.23.3-alpine
|
||||||
|
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
EXPOSE 443
|
||||||
42
proxy/nginx.conf
Normal file
42
proxy/nginx.conf
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# nginx/nginx.conf
|
||||||
|
|
||||||
|
events {
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
upstream front {
|
||||||
|
server front:3000;
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
# Redirect HTTP requests to HTTPS.
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
root /srv/public;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
|
||||||
|
server_name localhost;
|
||||||
|
root /srv/public;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ @front;
|
||||||
|
}
|
||||||
|
|
||||||
|
location @front {
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header X-Forwarded-Ssl on;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_pass http://front;
|
||||||
|
proxy_cookie_path / "/; HTTPOnly; Secure";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
readme.md
10
readme.md
@@ -4,7 +4,7 @@
|
|||||||
Edit the .env file in traque-front and add specify the following values:
|
Edit the .env file in traque-front and add specify the following values:
|
||||||
```
|
```
|
||||||
NEXT_PUBLIC_SOCKET_HOST = 'example.com'
|
NEXT_PUBLIC_SOCKET_HOST = 'example.com'
|
||||||
NEXT_PUBLIC_SOCKET_PORT = 3000
|
NEXT_PUBLIC_SOCKET_PORT = 3001
|
||||||
```
|
```
|
||||||
Where NEXT_PUBLIC_SOCKET_HOST is the host of the socket server and NEXT_PUBLIC_SOCKET_PORT is the port of the socket server.
|
Where NEXT_PUBLIC_SOCKET_HOST is the host of the socket server and NEXT_PUBLIC_SOCKET_PORT is the port of the socket server.
|
||||||
### Back end configuration
|
### Back end configuration
|
||||||
@@ -25,6 +25,8 @@ MAX_PENALTIES is the maximum number of penalties a user can have before loosing
|
|||||||
ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES is the time a user can be out of the zone before being penalized.
|
ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES is the time a user can be out of the zone before being penalized.
|
||||||
ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES is the maximum amount of time a user can wait before updating their position, after this period they will recieve a pennalty.
|
ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES is the maximum amount of time a user can wait before updating their position, after this period they will recieve a pennalty.
|
||||||
|
|
||||||
|
Note : make sure PORT and NEXT_PUBLIC_SOCKET_PORT are the same
|
||||||
|
|
||||||
### Running the project
|
### Running the project
|
||||||
#### Front end
|
#### Front end
|
||||||
To run the front end, navigate to the traque-front directory and run the following commands:
|
To run the front end, navigate to the traque-front directory and run the following commands:
|
||||||
@@ -43,5 +45,9 @@ Then navigate to the host and port specified in the .env file to access the appl
|
|||||||
https://example.com:3000
|
https://example.com:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
## Depployment
|
## Deployment
|
||||||
|
|
||||||
|
### SSL certificates
|
||||||
|
Put your certificate and private key in the traque-back/ssl folder. They need to be named `cert.pem` and `privkey.pem`.
|
||||||
|
You can then depploy the docker application with `docker compose up`
|
||||||
|
|
||||||
|
|||||||
4
traque-back/.gitignore
vendored
4
traque-back/.gitignore
vendored
@@ -1,8 +1,6 @@
|
|||||||
uploads/*
|
uploads/*
|
||||||
#https dev certificates
|
#https dev certificates
|
||||||
csr.pem
|
*.pem
|
||||||
key.pem
|
|
||||||
server.crt
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export function initAdminSocketHandler() {
|
|||||||
}
|
}
|
||||||
if (game.reorderTeams(newOrder)) {
|
if (game.reorderTeams(newOrder)) {
|
||||||
secureAdminBroadcast("teams", game.teams);
|
secureAdminBroadcast("teams", game.teams);
|
||||||
|
game.teams.forEach(t => sendUpdatedTeamInformations(t.id))
|
||||||
} else {
|
} else {
|
||||||
socket.emit("error", "Error reordering teams");
|
socket.emit("error", "Error reordering teams");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export default class Game {
|
|||||||
}
|
}
|
||||||
//The game has started
|
//The game has started
|
||||||
if (newState == GameState.PLAYING) {
|
if (newState == GameState.PLAYING) {
|
||||||
|
penaltyController.start();
|
||||||
if (!this.zone.ready()) {
|
if (!this.zone.ready()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ function onUpdateZone(zone) {
|
|||||||
|
|
||||||
export const game = new Game(onUpdateZone, onUpdateNewZone);
|
export const game = new Game(onUpdateZone, onUpdateNewZone);
|
||||||
export const penaltyController = new PenaltyController();
|
export const penaltyController = new PenaltyController();
|
||||||
penaltyController.init()
|
|
||||||
|
|
||||||
|
|
||||||
initAdminSocketHandler();
|
initAdminSocketHandler();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export class PenaltyController {
|
|||||||
this.checkIntervalId = null;
|
this.checkIntervalId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
start() {
|
||||||
this.outOfBoundsSince = {};
|
this.outOfBoundsSince = {};
|
||||||
if(this.checkIntervalId) {
|
if(this.checkIntervalId) {
|
||||||
clearInterval(this.checkIntervalId)
|
clearInterval(this.checkIntervalId)
|
||||||
@@ -62,6 +62,7 @@ export class PenaltyController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watchZone() {
|
watchZone() {
|
||||||
|
console.log("watching zone")
|
||||||
this.game.teams.forEach((team) => {
|
this.game.teams.forEach((team) => {
|
||||||
if (team.captured) { return }
|
if (team.captured) { return }
|
||||||
//All the informations are not ready yet
|
//All the informations are not ready yet
|
||||||
@@ -69,9 +70,11 @@ export class PenaltyController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isInCircle({lat: team.currentLocation[0], lng: team.currentLocation[1]}, this.game.zone.currentZone.center, this.game.zone.currentZone.radius)) {
|
if (!isInCircle({lat: team.currentLocation[0], lng: team.currentLocation[1]}, this.game.zone.currentZone.center, this.game.zone.currentZone.radius)) {
|
||||||
|
console.log("tema " + team.name + " out of zone")
|
||||||
//The team was not previously out of the zone
|
//The team was not previously out of the zone
|
||||||
if (!this.outOfBoundsSince[team.id]) {
|
if (!this.outOfBoundsSince[team.id]) {
|
||||||
this.outOfBoundsSince[team.id] = new Date();
|
this.outOfBoundsSince[team.id] = new Date();
|
||||||
|
console.log("tema " + team.name + " warned")
|
||||||
teamBroadcast(team.id, "warning", `You left the zone, you have ${process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES} minutes to get back in the marked area.`)
|
teamBroadcast(team.id, "warning", `You left the zone, you have ${process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES} minutes to get back in the marked area.`)
|
||||||
} else {
|
} else {
|
||||||
if (new Date() - this.outOfBoundsSince[team.id] > process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES * 60 * 1000) {
|
if (new Date() - this.outOfBoundsSince[team.id] > process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES * 60 * 1000) {
|
||||||
|
|||||||
67
traque-front/Dockerfile
Normal file
67
traque-front/Dockerfile
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
FROM node:18-alpine AS base
|
||||||
|
|
||||||
|
# Install dependencies only when needed
|
||||||
|
FROM base AS deps
|
||||||
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install dependencies based on the preferred package manager
|
||||||
|
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||||
|
elif [ -f package-lock.json ]; then npm ci; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Rebuild the source code only when needed
|
||||||
|
FROM base AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Next.js collects completely anonymous telemetry data about general usage.
|
||||||
|
# Learn more here: https://nextjs.org/telemetry
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
if [ -f yarn.lock ]; then yarn run build; \
|
||||||
|
elif [ -f package-lock.json ]; then npm run build; \
|
||||||
|
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||||
|
else echo "Lockfile not found." && exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Production image, copy all the files and run next
|
||||||
|
FROM base AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV production
|
||||||
|
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||||
|
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
|
||||||
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
|
||||||
|
# Set the correct permission for prerender cache
|
||||||
|
RUN mkdir .next
|
||||||
|
RUN chown nextjs:nodejs .next
|
||||||
|
|
||||||
|
# Automatically leverage output traces to reduce image size
|
||||||
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENV PORT 3000
|
||||||
|
|
||||||
|
# server.js is created by next build from the standalone output
|
||||||
|
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||||
|
CMD HOSTNAME="0.0.0.0" node server.js
|
||||||
@@ -4,6 +4,7 @@ import BlueButton, { GreenButton, RedButton } from "../util/button";
|
|||||||
import TextInput from "../util/textInput";
|
import TextInput from "../util/textInput";
|
||||||
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
||||||
import { EnemyTeamModal } from "./enemyTeamModal";
|
import { EnemyTeamModal } from "./enemyTeamModal";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
export default function ActionDrawer() {
|
export default function ActionDrawer() {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
@@ -29,10 +30,10 @@ export default function ActionDrawer() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"fixed w-screen bottom-0 z-10 bg-gray-100 flex justify-center rounded-t-2xl transition-all duration-200 flex flex-col " + (visible ? "h-full" : "h-20")}>
|
<div className={"fixed w-screen bottom-0 z-10 bg-gray-100 flex justify-center rounded-t-2xl transition-all duration-200 flex flex-col " + (visible ? "h-full" : "h-20")}>
|
||||||
<img src="/icons/arrow_up.png" className={"w-full object-scale-down h-ful max-h-20 transition-all cursor-pointer duration-200 " + (visible && "rotate-180")} onClick={() => setVisible(!visible)} />
|
<Image src="/icons/arrow_up.png" className={"w-full object-scale-down h-ful max-h-20 transition-all cursor-pointer duration-200 " + (visible && "rotate-180")} onClick={() => setVisible(!visible)} />
|
||||||
{visible && <div className="flex justify-between flex-col w-full h-full">
|
{visible && <div className="flex justify-between flex-col w-full h-full">
|
||||||
<div className="flex flex-row justify-around">
|
<div className="flex flex-row justify-around">
|
||||||
<img src="/icons/logout.png" onClick={logout} className='p-3 mx-2 w-14 h-14 bg-red-500 rounded-lg cursor-pointer bg-red z-20' />
|
<Image src="/icons/logout.png" onClick={logout} className='p-3 mx-2 w-14 h-14 bg-red-500 rounded-lg cursor-pointer bg-red z-20' />
|
||||||
</div>
|
</div>
|
||||||
<div className='shadow-2xl bg-white p-1 flex flex-col text-center mb-1 mx-auto w-4/5 rounded'>
|
<div className='shadow-2xl bg-white p-1 flex flex-col text-center mb-1 mx-auto w-4/5 rounded'>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import useGame from "@/hook/useGame";
|
import useGame from "@/hook/useGame";
|
||||||
import { RedButton } from "../util/button";
|
import { RedButton } from "../util/button";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
export function EnemyTeamModal({ visible, onClose }) {
|
export function EnemyTeamModal({ visible, onClose }) {
|
||||||
const { teamId, enemyName } = useGame();
|
const { teamId, enemyName } = useGame();
|
||||||
@@ -22,7 +23,7 @@ export function EnemyTeamModal({ visible, onClose }) {
|
|||||||
<div className='fixed w-screen h-screen bg-black bg-opacity-50 z-10 text-center'></div>
|
<div className='fixed w-screen h-screen bg-black bg-opacity-50 z-10 text-center'></div>
|
||||||
<div className='fixed w-11/12 h-5/6 p-5 z-20 mx-auto inset-x-0 my-auto inset-y-0 flex flex-col justify-center rounded-xl transition-all shadow-xl bg-white '>
|
<div className='fixed w-11/12 h-5/6 p-5 z-20 mx-auto inset-x-0 my-auto inset-y-0 flex flex-col justify-center rounded-xl transition-all shadow-xl bg-white '>
|
||||||
<h1 className="w-full text-center text-3xl mb-5">{enemyName}</h1>
|
<h1 className="w-full text-center text-3xl mb-5">{enemyName}</h1>
|
||||||
<img ref={imageRef} src={SERVER_URL + "/photo/enemy?team=" + teamId.toString()} className='w-full h-full object-contain' />
|
<Image ref={imageRef} src={SERVER_URL + "/photo/enemy?team=" + teamId.toString()} className='w-full h-full object-contain' />
|
||||||
<div className="h-20">
|
<div className="h-20">
|
||||||
<RedButton onClick={onClose}>Close</RedButton>
|
<RedButton onClick={onClose}>Close</RedButton>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export function LiveMap({ ...props }) {
|
|||||||
shadowSize: [41, 41]
|
shadowSize: [41, 41]
|
||||||
})}>
|
})}>
|
||||||
<Popup>
|
<Popup>
|
||||||
Position de l'ennemi
|
Position de l&aposennemi
|
||||||
</Popup>
|
</Popup>
|
||||||
</Marker>}
|
</Marker>}
|
||||||
<MapPan center={currentPosition} />
|
<MapPan center={currentPosition} />
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function Notification({socket }) {
|
|||||||
return (
|
return (
|
||||||
Object.keys(bgColorMap).map((key) =>
|
Object.keys(bgColorMap).map((key) =>
|
||||||
notification?.type == key &&
|
notification?.type == key &&
|
||||||
<div className={classNames + bgColorMap[key]} onClick={() => setVisible(false)}>
|
<div key={key} className={classNames + bgColorMap[key]} onClick={() => setVisible(false)}>
|
||||||
<p className='text-center text-xl'>{notification?.text}</p>
|
<p className='text-center text-xl'>{notification?.text}</p>
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
||||||
import useGame from "@/hook/useGame"
|
import useGame from "@/hook/useGame"
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
export default function PlacementOverlay() {
|
export default function PlacementOverlay() {
|
||||||
const { name, ready } = useGame();
|
const { name, ready } = useGame();
|
||||||
const {logout} = useTeamConnexion();
|
const {logout} = useTeamConnexion();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<img src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
<Image src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
||||||
<div className='fixed top-0 p-3 w-full bg-gray-300 shadow-xl rounded-b-xl flex flex-col z-10 justify-center items-center'>
|
<div className='fixed top-0 p-3 w-full bg-gray-300 shadow-xl rounded-b-xl flex flex-col z-10 justify-center items-center'>
|
||||||
<div className='text-2xl my-3'>Placement</div>
|
<div className='text-2xl my-3'>Placement</div>
|
||||||
<div className='text-md'>{name}</div>
|
<div className='text-md'>{name}</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import useGame from "@/hook/useGame"
|
import useGame from "@/hook/useGame"
|
||||||
import { GreenButton, LogoutButton } from "../util/button";
|
import { GreenButton, LogoutButton } from "../util/button";
|
||||||
import { useRef } from "react";
|
import { useRef } from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
export function WaitingScreen() {
|
export function WaitingScreen() {
|
||||||
const { name, teamId } = useGame();
|
const { name, teamId } = useGame();
|
||||||
@@ -35,13 +36,13 @@ export function WaitingScreen() {
|
|||||||
Jeu en préparation, veuillez patienter...
|
Jeu en préparation, veuillez patienter...
|
||||||
</div>
|
</div>
|
||||||
<div className='text-2xl text-center my-10'>
|
<div className='text-2xl text-center my-10'>
|
||||||
<p>Uploadez une photo où tous les membres de l'équipe sont visibles</p>
|
<p>Uploadez une photo où tous les membres de l&aposéquipe sont visibles</p>
|
||||||
<input type="file" name="file" accept="image/*" className=" my-5 block w-full text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"/>
|
<input type="file" name="file" accept="image/*" className=" my-5 block w-full text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"/>
|
||||||
<div className="h-20">
|
<div className="h-20">
|
||||||
<GreenButton onClick={sendImage}>Envoyer</GreenButton>
|
<GreenButton onClick={sendImage}>Envoyer</GreenButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{teamId && <img ref={imageRef} src={SERVER_URL + "/photo/my?team=" + teamId.toString()} className='w-screen h-1/2 object-contain' />}
|
{teamId && <Image ref={imageRef} src={SERVER_URL + "/photo/my?team=" + teamId.toString()} className='w-screen h-1/2 object-contain' />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
import { useTeamConnexion } from "@/context/teamConnexionContext";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
export default function BlueButton({ children, ...props }) {
|
export default function BlueButton({ children, ...props }) {
|
||||||
return (<button {...props} className="bg-blue-600 hover:bg-blue-500 text-lg ease-out duration-200 text-white w-full h-full p-4 shadow-sm rounded">
|
return (<button {...props} className="bg-blue-600 hover:bg-blue-500 text-lg ease-out duration-200 text-white w-full h-full p-4 shadow-sm rounded">
|
||||||
@@ -20,5 +21,5 @@ export function GreenButton({ children, ...props }) {
|
|||||||
|
|
||||||
export function LogoutButton() {
|
export function LogoutButton() {
|
||||||
const { logout } = useTeamConnexion();
|
const { logout } = useTeamConnexion();
|
||||||
return <img src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
return <Image src="/icons/logout.png" onClick={logout} className='w-12 h-12 bg-red-500 p-2 top-1 right-1 rounded-lg cursor-pointer bg-red fixed z-20' />
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {};
|
const nextConfig = {
|
||||||
|
experimental: {
|
||||||
|
outputStandalone: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
182
traque-front/package-lock.json
generated
182
traque-front/package-lock.json
generated
@@ -46,9 +46,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.24.1",
|
"version": "7.24.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
|
||||||
"integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
|
"integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@@ -130,54 +130,6 @@
|
|||||||
"react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0"
|
"react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@hello-pangea/dnd/node_modules/memoize-one": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
|
||||||
},
|
|
||||||
"node_modules/@hello-pangea/dnd/node_modules/react-is": {
|
|
||||||
"version": "18.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
|
||||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
|
||||||
},
|
|
||||||
"node_modules/@hello-pangea/dnd/node_modules/react-redux": {
|
|
||||||
"version": "8.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
|
|
||||||
"integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.12.1",
|
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
|
||||||
"@types/use-sync-external-store": "^0.0.3",
|
|
||||||
"hoist-non-react-statics": "^3.3.2",
|
|
||||||
"react-is": "^18.0.0",
|
|
||||||
"use-sync-external-store": "^1.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/react": "^16.8 || ^17.0 || ^18.0",
|
|
||||||
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
|
|
||||||
"react": "^16.8 || ^17.0 || ^18.0",
|
|
||||||
"react-dom": "^16.8 || ^17.0 || ^18.0",
|
|
||||||
"react-native": ">=0.59",
|
|
||||||
"redux": "^4 || ^5.0.0-beta.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/react": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"@types/react-dom": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"react-dom": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"react-native": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"redux": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.14",
|
"version": "0.11.14",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||||
@@ -206,9 +158,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/object-schema": {
|
"node_modules/@humanwhocodes/object-schema": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
|
||||||
"integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
|
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
@@ -508,15 +460,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rushstack/eslint-patch": {
|
"node_modules/@rushstack/eslint-patch": {
|
||||||
"version": "1.8.0",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.2.tgz",
|
||||||
"integrity": "sha512-0HejFckBN2W+ucM6cUOlwsByTKt9/+0tWhqUffNIcHqCXkthY/mZ7AuYPK/2IIaGWhdl0h+tICDO0ssLMd6XMQ==",
|
"integrity": "sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@socket.io/component-emitter": {
|
"node_modules/@socket.io/component-emitter": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz",
|
||||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
"integrity": "sha512-dzJtaDAAoXx4GCOJpbB2eG/Qj8VDpdwkLsWGzGm+0L7E8/434RyMbAHmk9ubXWVAb9nXmc44jUf8GKqVDiKezg=="
|
||||||
},
|
},
|
||||||
"node_modules/@swc/helpers": {
|
"node_modules/@swc/helpers": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
@@ -547,20 +499,14 @@
|
|||||||
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
|
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.69",
|
"version": "18.2.79",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.69.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz",
|
||||||
"integrity": "sha512-W1HOMUWY/1Yyw0ba5TkCV+oqynRjG7BnteBB+B7JmAK7iw3l2SW+VGOxL+akPweix6jk2NNJtyJKpn4TkpfK3Q==",
|
"integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/scheduler": {
|
|
||||||
"version": "0.16.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
|
||||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="
|
|
||||||
},
|
|
||||||
"node_modules/@types/use-sync-external-store": {
|
"node_modules/@types/use-sync-external-store": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||||
@@ -1165,9 +1111,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001600",
|
"version": "1.0.30001612",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz",
|
||||||
"integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==",
|
"integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1477,9 +1423,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.715",
|
"version": "1.4.747",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.715.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz",
|
||||||
"integrity": "sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg==",
|
"integrity": "sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
@@ -1522,9 +1468,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-abstract": {
|
"node_modules/es-abstract": {
|
||||||
"version": "1.23.2",
|
"version": "1.23.3",
|
||||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz",
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
|
||||||
"integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==",
|
"integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-buffer-byte-length": "^1.0.1",
|
"array-buffer-byte-length": "^1.0.1",
|
||||||
@@ -1566,11 +1512,11 @@
|
|||||||
"safe-regex-test": "^1.0.3",
|
"safe-regex-test": "^1.0.3",
|
||||||
"string.prototype.trim": "^1.2.9",
|
"string.prototype.trim": "^1.2.9",
|
||||||
"string.prototype.trimend": "^1.0.8",
|
"string.prototype.trimend": "^1.0.8",
|
||||||
"string.prototype.trimstart": "^1.0.7",
|
"string.prototype.trimstart": "^1.0.8",
|
||||||
"typed-array-buffer": "^1.0.2",
|
"typed-array-buffer": "^1.0.2",
|
||||||
"typed-array-byte-length": "^1.0.1",
|
"typed-array-byte-length": "^1.0.1",
|
||||||
"typed-array-byte-offset": "^1.0.2",
|
"typed-array-byte-offset": "^1.0.2",
|
||||||
"typed-array-length": "^1.0.5",
|
"typed-array-length": "^1.0.6",
|
||||||
"unbox-primitive": "^1.0.2",
|
"unbox-primitive": "^1.0.2",
|
||||||
"which-typed-array": "^1.1.15"
|
"which-typed-array": "^1.1.15"
|
||||||
},
|
},
|
||||||
@@ -2413,9 +2359,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/glob/node_modules/minimatch": {
|
"node_modules/glob/node_modules/minimatch": {
|
||||||
"version": "9.0.3",
|
"version": "9.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^2.0.1"
|
"brace-expansion": "^2.0.1"
|
||||||
@@ -3241,6 +3187,11 @@
|
|||||||
"node": "14 || >=16.14"
|
"node": "14 || >=16.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
|
},
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
@@ -3664,12 +3615,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/path-scurry": {
|
"node_modules/path-scurry": {
|
||||||
"version": "1.10.1",
|
"version": "1.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
|
||||||
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
|
"integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^9.1.1 || ^10.0.0",
|
"lru-cache": "^10.2.0",
|
||||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3976,6 +3927,49 @@
|
|||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-redux": {
|
||||||
|
"version": "8.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz",
|
||||||
|
"integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.12.1",
|
||||||
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
|
"@types/use-sync-external-store": "^0.0.3",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"react-is": "^18.0.0",
|
||||||
|
"use-sync-external-store": "^1.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-native": ">=0.59",
|
||||||
|
"redux": "^4 || ^5.0.0-beta.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-redux/node_modules/react-is": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
@@ -4611,9 +4605,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
|
||||||
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
|
"integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alloc/quick-lru": "^5.2.0",
|
"@alloc/quick-lru": "^5.2.0",
|
||||||
@@ -4624,7 +4618,7 @@
|
|||||||
"fast-glob": "^3.3.0",
|
"fast-glob": "^3.3.0",
|
||||||
"glob-parent": "^6.0.2",
|
"glob-parent": "^6.0.2",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"jiti": "^1.19.1",
|
"jiti": "^1.21.0",
|
||||||
"lilconfig": "^2.1.0",
|
"lilconfig": "^2.1.0",
|
||||||
"micromatch": "^4.0.5",
|
"micromatch": "^4.0.5",
|
||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
@@ -4833,9 +4827,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.4.3",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
Reference in New Issue
Block a user