-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFunc.js
More file actions
325 lines (279 loc) · 10.7 KB
/
Func.js
File metadata and controls
325 lines (279 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
// ============================================
// SERVICE WORKER REGISTRATION (PWA)
// ============================================
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('./service-worker.js')
.then(registration => {
console.log('Service Worker registered successfully:', registration);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
});
}
// ============================================
// LOGIN DATA MANAGEMENT
// ============================================
// Function to save Quole and TeamNum from logIn.html to sessionStorage
function saveLoginData() {
const quole = document.getElementById("quole").value;
const teamNum = document.getElementById("teamNum").value;
if (quole && teamNum) {
sessionStorage.setItem("quole", quole);
sessionStorage.setItem("teamNum", teamNum)
return true;
}
return false;
}
// Function to get Quole and TeamNum from sessionStorage
function getLoginData() {
return {
quole: sessionStorage.getItem("quole") || "",
teamNum: sessionStorage.getItem("teamNum") || ""
};
}
// Function to create JSON from Quole and counter (legacy)
function createJSON(counter, deliveryCounter) {
const loginData = getLoginData();
const jsonData = {
quole: loginData.quole,
teamNum: loginData.teamNum,
counter: counter,
deliveryCounter: deliveryCounter || 0,
timestamp: new Date().toISOString()
};
return JSON.stringify(jsonData, null, 2);
}
// Function to create auto data object
function createAutoData(counter, autoClimbed, deliveryCounter) {
const loginData = getLoginData();
return {
type: "auto",
quole: loginData.quole,
teamNum: loginData.teamNum,
autoCounter: counter,
autoClimbed: autoClimbed,
deliveryCounter: deliveryCounter || 0,
timestamp: new Date().toISOString()
};
}
// Function to create teleop data object
function createTeleopData(counter, climbLevel, deliveryCounter, climbTime, defense) {
const loginData = getLoginData();
return {
type: "teleop",
quole: loginData.quole,
teamNum: loginData.teamNum,
teleopCounter: counter,
climbLevel: climbLevel,
deliveryCounter: deliveryCounter || 0,
climbTime: climbTime || '',
defense: defense || '',
timestamp: new Date().toISOString()
};
}
// Legacy function for backward compatibility
function createMatchData(counter, deliveryCounter) {
const loginData = getLoginData();
return {
quole: loginData.quole,
teamNum: loginData.teamNum,
counter: counter,
deliveryCounter: deliveryCounter || 0,
timestamp: new Date().toISOString()
};
}
// Function to get the JSON (useful for game.html)
function getJSON() {
// Use the global counter variable (updated by counting function)
return createJSON(counter);
}
let counter = 0;
let deliveryCounter = 0; // new counter for delivery button
function counting() {
counter++;
document.getElementById("counter").innerText = counter;
}
function countingDelivery() {
deliveryCounter++;
const el = document.getElementById("deliveryCounter");
if (el) el.innerText = deliveryCounter;
}
// Function to save match data to localStorage
function saveMatchToLocalStorage(matchData) {
try {
// Get existing matches from localStorage
const existingMatches = getMatchesFromLocalStorage();
// Add new match
existingMatches.push(matchData);
// Save back to localStorage
localStorage.setItem('scoutingMatches', JSON.stringify(existingMatches));
return true;
} catch (e) {
console.error('Error saving to localStorage:', e);
return false;
}
}
// Function to retrieve all matches from localStorage
function getMatchesFromLocalStorage() {
try {
const stored = localStorage.getItem('scoutingMatches');
return stored ? JSON.parse(stored) : [];
} catch (e) {
console.error('Error reading from localStorage:', e);
return [];
}
}
// Function to get the current Google Sheets URL
function getGoogleSheetsUrl() {
return localStorage.getItem('googleSheetsScriptUrl') || null;
}
// Function to set or change the Google Sheets URL
function changeGoogleSheetsUrl() {
const currentUrl = getGoogleSheetsUrl();
let message = 'Enter your Google Apps Script Web App URL:';
if (currentUrl) {
message = 'Current URL: ' + currentUrl.substring(0, 50) + '...\n\n' +
'Enter a new URL to change it, or click Cancel to keep the current one:';
}
const newUrl = prompt(message);
if (newUrl === null) {
// User clicked Cancel
return { success: false, cancelled: true, message: 'URL change cancelled' };
}
if (newUrl.trim() === '') {
// User entered empty string - clear the URL
localStorage.removeItem('googleSheetsScriptUrl');
return { success: true, message: 'Google Sheets URL cleared. You will be prompted for a URL when exporting.' };
}
// Validate URL format (basic check)
if (!newUrl.startsWith('http://') && !newUrl.startsWith('https://')) {
return { success: false, message: 'Invalid URL format. URL must start with http:// or https://' };
}
// Save the new URL
localStorage.setItem('googleSheetsScriptUrl', newUrl.trim());
return { success: true, message: 'Google Sheets URL updated successfully!' };
}
// Function to export data to Google Sheets
async function exportToGoogleSheets(matchData) {
// Get the Google Apps Script Web App URL from localStorage or prompt user
let scriptUrl = localStorage.getItem('googleSheetsScriptUrl');
if (!scriptUrl) {
scriptUrl = prompt('Please enter your Google Apps Script Web App URL:\n\n(If you haven\'t set it up yet, see GOOGLE_SHEETS_SETUP.md for instructions)');
if (scriptUrl) {
localStorage.setItem('googleSheetsScriptUrl', scriptUrl);
} else {
return { success: false, message: 'Google Sheets export cancelled - no URL provided' };
}
}
try {
const response = await fetch(scriptUrl, {
method: 'POST',
mode: 'no-cors', // Google Apps Script Web Apps require no-cors
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(matchData)
});
// Note: With no-cors mode, we can't read the response, but the data should be sent
return { success: true, message: 'Data sent to Google Sheets successfully!' };
} catch (error) {
console.error('Error exporting to Google Sheets:', error);
return { success: false, message: 'Error exporting to Google Sheets: ' + error.message };
}
}
// Function to download data as CSV
function downloadCSV(matchData) {
// Convert match data to CSV format based on type
let headers, row;
if (matchData.type === 'auto') {
headers = ['Type', 'Quole', 'Team Number', 'Auto Counter', 'Auto Climbed', 'Delivery Counter', 'Timestamp'];
row = [
'auto',
matchData.quole || '',
matchData.teamNum || '',
matchData.autoCounter || '',
matchData.autoClimbed ? 'True' : 'False',
matchData.deliveryCounter || 0,
matchData.timestamp || ''
];
} else if (matchData.type === 'teleop') {
headers = ['Type', 'Quole', 'Team Number', 'Teleop Counter', 'Climb Level', 'Climb Time', 'Defense', 'Delivery Counter', 'Timestamp'];
row = [
'teleop',
matchData.quole || '',
matchData.teamNum || '',
matchData.teleopCounter || '',
matchData.climbLevel || '',
matchData.climbTime || '',
matchData.defense || '',
matchData.deliveryCounter || 0,
matchData.timestamp || ''
];
} else {
// Legacy format
headers = ['Quole', 'Team Number', 'Counter', 'Timestamp'];
row = [
matchData.quole || '',
matchData.teamNum || '',
matchData.counter || '',
matchData.timestamp || ''
];
}
// Escape values that contain commas or quotes
const escapeCSV = (value) => {
if (value === null || value === undefined) return '';
const stringValue = String(value);
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
return '"' + stringValue.replace(/"/g, '""') + '"';
}
return stringValue;
};
const csvContent = [
headers.map(escapeCSV).join(','),
row.map(escapeCSV).join(',')
].join('\n');
// Create download link
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', `scouting_data_${new Date().toISOString().split('T')[0]}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
return { success: true, message: 'CSV file downloaded successfully!' };
}
// Main function to save and export match data
async function showData(){
// Get current match data
const matchData = createMatchData(counter);
// Save to localStorage
const saved = saveMatchToLocalStorage(matchData);
if (!saved) {
alert('Warning: Could not save data to local storage.');
}
// Try to export to Google Sheets
const exportResult = await exportToGoogleSheets(matchData);
if (exportResult.success) {
alert('Match data saved and exported to Google Sheets!\n\n' + exportResult.message);
} else {
// If Google Sheets export fails, offer CSV download
const useCSV = confirm('Google Sheets export failed or was cancelled.\n\n' +
exportResult.message +
'\n\nWould you like to download the data as a CSV file instead?');
if (useCSV) {
const csvResult = downloadCSV(matchData);
if (csvResult.success) {
alert(csvResult.message);
}
}
}
// Reset counter for next match
counter = 0;
if (document.getElementById("counter")) {
document.getElementById("counter").innerText = counter;
}
}