|
|
|
@ -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])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|