Add /fiches

This commit is contained in:
pikiou
2022-06-25 02:12:25 +02:00
parent 88549bf42d
commit 3a5f2792c9
26 changed files with 601 additions and 49 deletions

View File

@@ -0,0 +1,167 @@
import React, { memo } from "react"
import { useSelector } from "react-redux"
import styles from "./styles.module.scss"
// import styles from "./styles.module.scss"
import { fetchBoxListIfNeed, selectContainerSortedDetailedBoxes } from "../../store/boxList"
import {
fetchVolunteerDetailedKnowledgeListIfNeed,
selectVolunteerDetailedKnowledgeList,
} from "../../store/volunteerDetailedKnowledgeList"
import { DetailedBox } from "../../services/boxes"
import { VolunteerDetailedKnowledge } from "../../services/volunteers"
const KnowledgeCard: React.FC = (): JSX.Element | null => {
const detailedBoxes = useSelector(selectContainerSortedDetailedBoxes) as DetailedBox[]
const volunteerDetailedKnowledgeList = useSelector(selectVolunteerDetailedKnowledgeList)
return <>{detailedBoxes.map((box) => boxElement(box, volunteerDetailedKnowledgeList))}</>
}
const boxElement = (
box: DetailedBox,
volunteerDetailedKnowledgeList: VolunteerDetailedKnowledge[]
): JSX.Element => {
const playerCount: string =
box.playersMin === box.playersMax
? `${box.playersMin}`
: `${box.playersMin} à ${box.playersMax}`
const typeStyle = {
"": null,
Ambiance: styles.verteImg,
Famille: styles.orangeImg,
Expert: styles.rougeImg,
}[box.type]
const year = new Date().getFullYear()
const okVolunteers = wiseVolunteers(volunteerDetailedKnowledgeList, box.gameId, "ok")
const bofVolunteers = wiseVolunteers(volunteerDetailedKnowledgeList, box.gameId, "bof")
const someOk = okVolunteers.length > 0
const someBof = bofVolunteers.length > 0
const some = someOk || someBof
return (
<div key={box.id} className={styles.card}>
<header className={styles.header}>{box.title}</header>
<div className={styles.showUnknownOnlyLabeldetail}>
<div className={styles.masteryContainer}>
<table>
<tbody>
<tr>
<td className={styles.imageContainer}>
<img
className={styles.gameImage}
src={box.bggPhoto}
alt="Board game box"
/>
</td>
<td className={styles.tableBenevoles}>
<table className={styles.benevolesContainer}>
<tbody>
<tr className={styles.okHeader}>
<td>Ils maîtrisent</td>
</tr>
<tr className={styles.listOk}>
<td>
<div className={styles.nicknameContainer}>
{okVolunteers}
{!some && (
<>
Désolé aucun bénévole n'y a joué, il
va falloir lire la règle.
</>
)}
{!someOk && someBof && (
<>
Aucun bénévole ne maîtrise les
règles de ce jeu.
</>
)}
</div>
</td>
</tr>
{someBof && (
<tr className={styles.bofHeader}>
<td>Ils connaissent</td>
</tr>
)}
{someBof && (
<tr className={styles.listBof}>
<td>
<div className={styles.nicknameContainer}>
{bofVolunteers}
</div>
</td>
</tr>
)}
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div className={styles.gamedetailContainer}>
<table>
<tbody>
<tr>
<td className={styles.numberOfPlayersImgContainer}>
<div className={styles.numberOfPlayersImg} />
</td>
<td className={styles.numberOfPlayers}>{playerCount}</td>
<td className={styles.durationImgContainer}>
<div className={styles.durationImg} />
</td>
<td className={styles.duration}>{box.duration} min</td>
<td className={styles.typeImgContainer}>
<div className={typeStyle} />
</td>
<td className={styles.type}>{box.type}</td>
<td className={styles.pppImgContainer}>
<div className={styles.pppImg} />
</td>
</tr>
</tbody>
</table>
</div>
</div>
<footer className={styles.footer}>
<div className={styles.year}>{year}</div>
<div className={styles.container}>{box.container}</div>
</footer>
</div>
)
}
function wiseVolunteers(
volunteersKnowledge: VolunteerDetailedKnowledge[],
gameId: number,
wiseness: "ok" | "bof"
): JSX.Element[] {
return volunteersKnowledge
.filter(
(v) =>
v[wiseness].includes(gameId) &&
(v.dayWishes.includes("S") || v.dayWishes.includes("D"))
)
.map((v) => (
<div key={v.id} className={styles.nickname}>
<b>{v.nickname.charAt(0).toUpperCase()}</b>
{v.nickname.substring(1)}
{v.dayWishes.includes("S") && !v.dayWishes.includes("D") && (
<span className={styles.oneDayOnly}>(sam.)</span>
)}
{!v.dayWishes.includes("S") && v.dayWishes.includes("D") && (
<span className={styles.oneDayOnly}>(dim.)</span>
)}
</div>
))
}
export default memo(KnowledgeCard)
export const fetchFor = [fetchBoxListIfNeed, fetchVolunteerDetailedKnowledgeListIfNeed]

View File

@@ -122,3 +122,181 @@
background-color: $color-active-niet;
}
}
/* Cards */
.card {
display: inline-block;
vertical-align: top;
width: 48vw;
margin: 1vw;
break-inside: avoid;
border: $color-black solid 0.1vw;
}
.header {
color: $color-white;
background-color: #e18502;
text-align: center;
font-size: 2.5vw;
line-height: 5vw;
font-family: $font-pel;
}
.imageContainer {
padding: 1vw;
}
.benevolesContainer {
width: 100%;
}
.tableBenevoles {
width: 100%;
vertical-align: top;
padding-top: 1vw;
}
.gameImage {
width: 10vw;
}
.okHeader,
.bofHeader {
text-align: center;
width: 100%;
font-size: 1.8vw;
font-weight: bold;
}
.okHeader {
background-color: #9dba5d;
}
.listOk {
text-align: center;
}
.listOk td {
padding-top: 15px;
padding-bottom: 15px;
}
.bofHeader {
background-color: #cb9902;
}
.listBof {
text-align: center;
}
.listBof td {
padding-top: 15px;
padding-bottom: 15px;
}
.nicknameContainer {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
align-content: center;
gap: 0.5vw;
}
.nickname {
flex: 1 1 auto;
white-space: nowrap;
}
.numberOfPlayersImgContainer {
width: 6.3vw;
}
.numberOfPlayersImg {
width: 6vw;
height: 4vw;
background: url("../../app/img/knowledgeCards/nombre_joueurs-fiche.png") no-repeat center center;
background-size: cover;
}
.numberOfPlayers {
font-family: $font-pel;
font-size: 1.6vw;
white-space: nowrap;
}
.durationImgContainer {
width: 6.1vw;
padding-left: 1vw;
}
.durationImg {
width: 6vw;
height: 4vw;
background: url("../../app/img/knowledgeCards/duree-fiche.png") no-repeat center center;
background-size: cover;
}
.duration {
font-family: $font-pel;
font-size: 1.6vw;
white-space: nowrap;
}
.typeImgContainer {
width: 6.2vw;
padding-left: 1.1vw;
}
.verteImg,
.orangeImg,
.rougeImg {
width: 6vw;
height: 6vw;
background-size: cover;
}
.verteImg {
background: url("../../app/img/knowledgeCards/jauge-verte.png") no-repeat center center;
}
.orangeImg {
background: url("../../app/img/knowledgeCards/jauge-orange.png") no-repeat center center;
}
.rougeImg {
background: url("../../app/img/knowledgeCards/jauge-rouge.png") no-repeat center center;
}
.type {
font-family: $font-pel;
font-size: 1.6vw;
white-space: nowrap;
}
.pppImgContainer {
width: 6vw;
padding-left: 0.7vw;
}
.pppImg {
width: 6vw;
height: 3.4vw;
background: url("../../app/img/knowledgeCards/ppp-fiche-ko-trespetit.png") no-repeat center
center;
background-size: cover;
}
.oneDayOnly {
color: $color-red;
}
.footer {
height: 3vw;
font-family: $font-pel;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-content: center;
background-color: #96b397;
font-style: oblique;
}
.year {
flex: 0 1 auto;
align-self: center;
margin-left: 1vw;
font-size: 1vw;
}
.container {
flex: 0 1 auto;
align-self: center;
margin-right: 1vw;
font-size: 1.5vw;
}