1- import { NotLinkedToTba } from "@/lib/client/ClientUtils" ;
1+ import { download , NotLinkedToTba } from "@/lib/client/ClientUtils" ;
22import { defaultGameId } from "@/lib/client/GameId" ;
33import { Round } from "@/lib/client/StatsMath" ;
44import { games } from "@/lib/games" ;
5- import { Competition , Pitreport , Report , Team } from "@/lib/Types" ;
5+ import { Competition , MatchType , Pitreport , Report , Team } from "@/lib/Types" ;
66import Link from "next/link" ;
7- import { ChangeEvent } from "react" ;
7+ import { ChangeEvent , useState } from "react" ;
88import { BsGearFill , BsClipboard2Check } from "react-icons/bs" ;
99import { FaSync , FaBinoculars , FaUserCheck , FaDatabase } from "react-icons/fa" ;
1010import { FaUserGroup } from "react-icons/fa6" ;
11+ import ClientApi from "@/lib/api/ClientApi" ;
12+
13+ const api = new ClientApi ( ) ;
1114
1215export default function InsightsAndSettingsCard ( props : {
13- showSettings : boolean ;
14- setShowSettings : ( value : boolean ) => void ;
1516 isManager : boolean | undefined ;
1617 comp : Competition | undefined ;
1718 reloadCompetition : ( ) => void ;
1819 assignScouters : ( ) => void ;
19- exportAsCsv : ( ) => void ;
20- exportPending : boolean ;
2120 showSubmittedMatches : boolean ;
2221 toggleShowSubmittedMatches : ( ) => void ;
2322 assigningMatches : boolean ;
2423 regeneratePitReports : ( ) => void ;
25- newCompName : string | undefined ;
26- setNewCompName : ( value : string ) => void ;
27- newCompTbaId : string | undefined ;
28- setNewCompTbaId : ( value : string ) => void ;
29- saveCompChanges : ( ) => void ;
30- redAlliance : number [ ] ;
31- setRedAlliance : ( value : number [ ] ) => void ;
32- blueAlliance : number [ ] ;
33- setBlueAlliance : ( value : number [ ] ) => void ;
34- matchNumber : number | undefined ;
35- setMatchNumber : ( value : number ) => void ;
36- createMatch : ( ) => void ;
37- teamToAdd : number ;
38- setTeamToAdd : ( value : number ) => void ;
39- addTeam : ( ) => void ;
4024 submittedReports : number | undefined ;
4125 reports : Report [ ] ;
4226 loadingScoutStats : boolean ;
4327 pitreports : Pitreport [ ] ;
4428 submittedPitreports : number | undefined ;
45- togglePublicData : ( e : ChangeEvent < HTMLInputElement > ) => void ;
4629 seasonSlug : string | undefined ;
4730 team : Team | undefined ;
48- allianceIndices : number [ ] ;
4931} ) {
32+ const [ showSettings , setShowSettings ] = useState ( false ) ;
5033 const {
51- showSettings,
52- setShowSettings,
5334 isManager,
5435 comp,
5536 reloadCompetition,
5637 assignScouters,
57- exportAsCsv,
58- exportPending,
5938 showSubmittedMatches,
6039 toggleShowSubmittedMatches,
6140 assigningMatches,
62- newCompName,
63- setNewCompName,
64- newCompTbaId,
65- setNewCompTbaId,
66- saveCompChanges,
67- redAlliance,
68- setRedAlliance,
69- blueAlliance,
70- setBlueAlliance,
71- matchNumber,
72- setMatchNumber,
73- createMatch,
74- teamToAdd,
75- setTeamToAdd,
76- addTeam,
7741 submittedReports,
7842 reports,
7943 loadingScoutStats,
8044 pitreports,
8145 submittedPitreports,
82- togglePublicData,
8346 seasonSlug,
8447 team,
85- allianceIndices,
8648 } = props ;
49+ const [ newCompName , setNewCompName ] = useState ( comp ?. name ) ;
50+ const [ newCompTbaId , setNewCompTbaId ] = useState ( comp ?. tbaId ) ;
51+ const [ exportPending , setExportPending ] = useState ( false ) ;
52+ const [ teamToAdd , setTeamToAdd ] = useState < number > ( 0 ) ;
53+ const [ blueAlliance , setBlueAlliance ] = useState < number [ ] > ( [ ] ) ;
54+ const [ redAlliance , setRedAlliance ] = useState < number [ ] > ( [ ] ) ;
55+ const [ matchNumber , setMatchNumber ] = useState < number | undefined > ( undefined ) ;
56+
57+ const exportAsCsv = async ( ) => {
58+ setExportPending ( true ) ;
59+
60+ const res = await api . exportCompAsCsv ( comp ?. _id ! ) . catch ( ( e ) => {
61+ console . error ( e ) ;
62+ return { csv : undefined } ;
63+ } ) ;
64+
65+ if ( ! res ) {
66+ console . error ( "failed to export" ) ;
67+ }
68+
69+ if ( res . csv ) {
70+ download ( `${ comp ?. name ?? "Competition" } .csv` , res . csv , "text/csv" ) ;
71+ } else {
72+ console . error ( "No CSV data returned from server" ) ;
73+ }
74+
75+ setExportPending ( false ) ;
76+ } ;
77+
78+ const createMatch = async ( ) => {
79+ try {
80+ await api . createMatch (
81+ comp ?. _id ! ,
82+ Number ( matchNumber ) ,
83+ 0 ,
84+ MatchType . Qualifying ,
85+ blueAlliance as number [ ] ,
86+ redAlliance as number [ ] ,
87+ ) ;
88+ } catch ( e ) {
89+ console . error ( e ) ;
90+ }
91+
92+ location . reload ( ) ;
93+ } ;
94+
95+ const allianceIndices : number [ ] = [ ] ;
96+ for ( let i = 0 ; i < games [ comp ?. gameId ?? defaultGameId ] . allianceSize ; i ++ ) {
97+ allianceIndices . push ( i ) ;
98+ }
99+
100+ async function saveCompChanges ( ) {
101+ // Check if tbaId is valid
102+ if ( ! comp ?. tbaId || ! comp ?. name || ! comp ?. _id ) return ;
103+
104+ let tbaId = newCompTbaId ;
105+ const autoFillData = await api . competitionAutofill ( tbaId ?? "" ) ;
106+ if (
107+ ! autoFillData ?. name &&
108+ ! confirm ( `Invalid TBA ID: ${ tbaId } . Save changes anyway?` )
109+ )
110+ return ;
111+
112+ await api . updateCompNameAndTbaId (
113+ comp ?. _id ,
114+ newCompName ?? "Unnamed" ,
115+ tbaId ?? NotLinkedToTba ,
116+ ) ;
117+ location . reload ( ) ;
118+ }
119+
120+ function togglePublicData ( e : ChangeEvent < HTMLInputElement > ) {
121+ if ( ! comp ?. _id ) return ;
122+ api . setCompPublicData ( comp ?. _id , e . target . checked ) ;
123+ }
124+
125+ function addTeam ( ) {
126+ console . log ( "Adding pit report for team" , teamToAdd ) ;
127+ if ( ! teamToAdd || teamToAdd < 1 || ! comp ?. _id ) return ;
128+
129+ api
130+ . createPitReportForTeam ( teamToAdd , comp ?. _id )
131+ // We can't just pass location.reload, it will throw "illegal invocation." I don't know why. -Renato
132+ . finally ( ( ) => location . reload ( ) ) ;
133+ }
87134
88135 return (
89136 < div className = "w-full card bg-base-200 shadow-xl" >
@@ -367,7 +414,7 @@ export default function InsightsAndSettingsCard(props: {
367414 ? ( + (
368415 Round ( submittedReports / reports . length ) * 100
369416 ) ) . toFixed ( 0 )
370- : "? " }
417+ : "0 " }
371418 %
372419 </ div >
373420 < div className = "stat-desc" > </ div >
@@ -394,7 +441,7 @@ export default function InsightsAndSettingsCard(props: {
394441 ? ( + (
395442 Round ( submittedReports / reports . length ) * 100
396443 ) ) . toFixed ( 0 )
397- : "? " }
444+ : "0 " }
398445 %
399446 </ div >
400447 < div className = "stat-desc" >
@@ -412,12 +459,9 @@ export default function InsightsAndSettingsCard(props: {
412459 < FaUserGroup size = { 40 } > </ FaUserGroup >
413460 </ div >
414461 < div className = "stat-value text-primary" >
415- { ! submittedPitreports && submittedPitreports !== 0
416- ? "?"
417- : submittedPitreports }
418- /
462+ { ! submittedPitreports ? "0" : submittedPitreports } /
419463 { ! pitreports || pitreports . length === 0
420- ? "? "
464+ ? "0 "
421465 : pitreports . length }
422466 </ div >
423467 </ div >
0 commit comments