Vivien DUFOUR 1 year ago
parent 3da28f828d
commit 08c75d025d

@ -1,2 +1,2 @@
#VITE_API_ENDPOINT=https://iqball.maxou.dev/api/dotnet-master
VITE_API_ENDPOINT=http://localhost:5254
#VITE_API_ENDPOINT=https://iqball.maxou.dev/api/dotnet-shared-tactic
VITE_API_ENDPOINT=http://iutclinfb1007l:5254

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

2214
composer.lock generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

@ -13,6 +13,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-icons": "^5.0.1",
"react-router-dom": "^6.22.0",
"typescript": "^5.2.2",
"vite": "^4.5.0",

Before

Width:  |  Height:  |  Size: 747 B

After

Width:  |  Height:  |  Size: 747 B

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 507 B

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 732 B

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 335 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 216 B

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -1,8 +1,11 @@
import "../style/home/home.css"
import { useNavigate } from "react-router-dom"
import { useEffect, useState } from "react"
import { User } from "../model/User.ts"
import { useAppFetcher } from "../App.tsx"
import {RefObject, useEffect, useRef, useState} from "react"
import {useAppFetcher, useUser} from "../App.tsx"
import {NULL_POS} from "../geo/Pos";
import {contains} from "../geo/Box";
import Draggable from "react-draggable"
import { FaShare } from "react-icons/fa"
interface Tactic {
id: number
@ -19,12 +22,15 @@ interface Team {
}
export default function HomePage() {
type UserDataResponse = { user?: User; tactics: Tactic[]; teams: Team[] }
const [{ tactics, teams }, setInfo] = useState<UserDataResponse>({
type UserDataResponse = { tactics: Tactic[]; teams: Team[]; sharedTactics: Tactic[] }
const [{ teams, tactics, sharedTactics }, setInfo] = useState<UserDataResponse>({
tactics: [],
teams: [],
sharedTactics: [],
})
console.log(sharedTactics)
const navigate = useNavigate()
const fetcher = useAppFetcher()
@ -45,7 +51,7 @@ export default function HomePage() {
const lastTactics = tactics.slice(0, 5)
return (
<Home teams={teams!} allTactics={tactics!} lastTactics={lastTactics} />
<Home teams={teams!} allTactics={tactics!} lastTactics={lastTactics} sharedTactics={sharedTactics!} />
)
}
@ -53,10 +59,12 @@ function Home({
lastTactics,
allTactics,
teams,
sharedTactics,
}: {
lastTactics: Tactic[]
allTactics: Tactic[]
teams: Team[]
sharedTactics: Tactic[]
}) {
return (
<div id="main">
@ -64,6 +72,7 @@ function Home({
lastTactics={lastTactics}
allTactics={allTactics}
teams={teams}
sharedTactics={sharedTactics}
/>
</div>
)
@ -73,16 +82,18 @@ function Body({
lastTactics,
allTactics,
teams,
sharedTactics,
}: {
lastTactics: Tactic[]
allTactics: Tactic[]
teams: Team[]
sharedTactics: Tactic[]
}) {
const widthPersonalSpace = 78
const widthSideMenu = 100 - widthPersonalSpace
return (
<div id="body">
<PersonalSpace width={widthPersonalSpace} allTactics={allTactics} />
<PersonalSpace width={widthPersonalSpace} allTactics={allTactics} teams={teams} sharedTactics={sharedTactics} />
<SideMenu
width={widthSideMenu}
lastTactics={lastTactics}
@ -118,9 +129,13 @@ function SideMenu({
function PersonalSpace({
width,
allTactics,
teams,
sharedTactics,
}: {
width: number
allTactics: Tactic[]
teams: Team[]
sharedTactics: Tactic[]
}) {
return (
<div
@ -129,7 +144,7 @@ function PersonalSpace({
width: width + "%",
}}>
<TitlePersonalSpace />
<BodyPersonalSpace allTactics={allTactics} />
<BodyPersonalSpace allTactics={allTactics} teams={teams} sharedTactics={sharedTactics}/>
</div>
)
}
@ -142,8 +157,8 @@ function TitlePersonalSpace() {
)
}
function TableData({ allTactics }: { allTactics: Tactic[] }) {
const nbRow = Math.floor(allTactics.length / 3) + 1
function TableData({ allTactics, teams, isShared }: { allTactics: Tactic[], teams : Team[], isShared: boolean }) {
const nbRow = Math.floor(allTactics.length / 3 + 1)
const listTactic = Array(nbRow)
for (let i = 0; i < nbRow; i++) {
listTactic[i] = Array(0)
@ -159,19 +174,15 @@ function TableData({ allTactics }: { allTactics: Tactic[] }) {
}
})
const navigate = useNavigate()
i = 0
while (i < nbRow) {
listTactic[i] = listTactic[i].map((tactic: Tactic) => (
<td
key={tactic.id}
className="data"
onClick={() => {
navigate("/tactic/" + tactic.id + "/edit")
}}>
{truncateString(tactic.name, 25)}
</td>
listTactic[i] = listTactic[i].map((tactic: Tactic, index: number) => (
<DraggableTableDataElement
key={index}
tactic={tactic}
teams={teams}
isShared={isShared}
/>
))
i++
}
@ -188,7 +199,80 @@ function TableData({ allTactics }: { allTactics: Tactic[] }) {
))
}
function BodyPersonalSpace({ allTactics }: { allTactics: Tactic[] }) {
function DraggableTableDataElement({
tactic,
teams,
isShared,
}: {
tactic: Tactic
teams: Team[]
isShared: boolean
}) {
const ref = useRef<HTMLDivElement>(null)
const [dragging, setDragging] = useState(false)
const [hovered, setHovered] = useState(false)
const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation()
if (!dragging) {
const userEmail = window.prompt(
"Entrez l'email à qui partager la tactique :",
)
if (userEmail != null) {
onShareTactic(userEmail, tactic)
}
} else {
setDragging(false)
}
}
const navigate = useNavigate()
return (
<Draggable
position={NULL_POS}
nodeRef={ref}
onDrag={() => setDragging(true)}
onStop={() => {
if (dragging) {
if (ref.current) {
onDropTactic(
ref.current.getBoundingClientRect(),
tactic,
teams,
)
}
}
}}>
<td
key={tactic.id}
ref={ref as RefObject<HTMLTableDataCellElement>}
className="data"
onClick={() => {
if (!dragging) {
navigate("/tactic/" + tactic.id + "/edit")
} else {
setDragging(false)
}
}}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}>
{truncateString(tactic.name, 25)}
{hovered && (
<div className="share-icon-container">
<button
className="share-button share-icon-button"
onClick={handleButtonClick}>
<FaShare className="share-icon" />
</button>
</div>
)}
</td>
</Draggable>
)
}
function BodyPersonalSpace({ allTactics, teams, sharedTactics }: { allTactics: Tactic[], teams: Team[], sharedTactics: Tactic[]}) {
return (
<div id="body-personal-space">
{allTactics.length == 0 ? (
@ -196,7 +280,8 @@ function BodyPersonalSpace({ allTactics }: { allTactics: Tactic[] }) {
) : (
<table>
<tbody key="tbody">
<TableData allTactics={allTactics} />
<TableData allTactics={allTactics} teams={teams} isShared={false}/>
<TableData allTactics={sharedTactics} teams={teams} isShared={true}/>
</tbody>
</table>
)}
@ -292,3 +377,55 @@ function truncateString(name: string, limit: number): string {
}
return name
}
function onDropTactic(ref: DOMRect, tactic: Tactic, teams: Team[]) {
let shared = false
for (const team of teams) {
if (
contains(
ref,
document
.getElementById(`button-team-${team.id}`)!
.getBoundingClientRect(),
)
) {
if (!shared) {
shareTacticToTeam(tactic, team)
shared = true
}
}
}
}
async function onShareTactic(email: string, tactic: Tactic) {
const fetcher = useAppFetcher()
const [user, ] = useUser()
useEffect(() => {
async function shareTactic() {
const response = await fetcher.fetchAPI("user/share-tactic", {tacticId: tactic.id, userId: user})
}
shareTactic()
}, [fetcher])
}
async function shareTacticToTeam(tactic: Tactic, team: Team) {
const fetcher = useAppFetcher()
if (
confirm(
"Etes-vous sûr de vouloir partager la tactique " +
tactic.name +
" avec l'équipe " +
team.name,
)
) {
useEffect(() => {
async function shareTacticToTeam() {
const response = await fetcher.fetchAPI("team/share-tactic", {tacticId: tactic.id, teamId: team.id})
}
shareTacticToTeam()
}, [fetcher])
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save