Upload folder using huggingface_hub
Browse files
client/src/pages/TutorialTasks.tsx
CHANGED
|
@@ -113,6 +113,7 @@ const TutorialTasks: React.FC = () => {
|
|
| 113 |
};
|
| 114 |
const [loading, setLoading] = useState(true);
|
| 115 |
const [submitting, setSubmitting] = useState<{[key: string]: boolean}>({});
|
|
|
|
| 116 |
const [translationText, setTranslationText] = useState<{[key: string]: string}>({});
|
| 117 |
const [selectedGroups, setSelectedGroups] = useState<{[key: string]: number}>({});
|
| 118 |
const [expandedSections, setExpandedSections] = useState<{[key: string]: boolean}>({});
|
|
@@ -444,6 +445,23 @@ const TutorialTasks: React.FC = () => {
|
|
| 444 |
}
|
| 445 |
};
|
| 446 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
const handleFileUpload = async (file: File): Promise<string> => {
|
| 448 |
try {
|
| 449 |
setUploading(true);
|
|
@@ -1132,17 +1150,18 @@ const TutorialTasks: React.FC = () => {
|
|
| 1132 |
<div className="mt-2 flex items-center gap-2">
|
| 1133 |
<span className="text-xs text-ui-text/70">Visibility</span>
|
| 1134 |
<label className="switch">
|
| 1135 |
-
<input type="checkbox" checked={
|
| 1136 |
try {
|
| 1137 |
const base = (((api.defaults as any)?.baseURL as string)||'').replace(/\/$/,'');
|
| 1138 |
const nextHidden = e.currentTarget.checked;
|
| 1139 |
await fetch(`${base}/api/admin/weeks/tutorial/${selectedWeek}/visibility`,{ method:'PUT', headers:{ 'Content-Type':'application/json', 'Authorization': localStorage.getItem('token')?`Bearer ${localStorage.getItem('token')}`:'', 'user-role':'admin' }, body: JSON.stringify({ hidden: nextHidden }) });
|
|
|
|
| 1140 |
await fetchTutorialTasks(true);
|
| 1141 |
} catch (err) { console.error(err);}
|
| 1142 |
}}/>
|
| 1143 |
<span className="slider" />
|
| 1144 |
</label>
|
| 1145 |
-
<span className="text-xs">{
|
| 1146 |
</div>
|
| 1147 |
)}
|
| 1148 |
</div>
|
|
|
|
| 113 |
};
|
| 114 |
const [loading, setLoading] = useState(true);
|
| 115 |
const [submitting, setSubmitting] = useState<{[key: string]: boolean}>({});
|
| 116 |
+
const [isWeekHidden, setIsWeekHidden] = useState<boolean>(false);
|
| 117 |
const [translationText, setTranslationText] = useState<{[key: string]: string}>({});
|
| 118 |
const [selectedGroups, setSelectedGroups] = useState<{[key: string]: number}>({});
|
| 119 |
const [expandedSections, setExpandedSections] = useState<{[key: string]: boolean}>({});
|
|
|
|
| 445 |
}
|
| 446 |
};
|
| 447 |
|
| 448 |
+
useEffect(() => {
|
| 449 |
+
const loadVisibility = async () => {
|
| 450 |
+
try {
|
| 451 |
+
const base = (((api.defaults as any)?.baseURL as string) || '').replace(/\/$/, '');
|
| 452 |
+
const resp = await fetch(`${base}/api/admin/weeks/tutorial/${selectedWeek}/visibility`, {
|
| 453 |
+
headers: {
|
| 454 |
+
'Authorization': localStorage.getItem('token') ? `Bearer ${localStorage.getItem('token')}` : '',
|
| 455 |
+
'user-role': 'admin'
|
| 456 |
+
}
|
| 457 |
+
});
|
| 458 |
+
const json = await resp.json().catch(() => ({}));
|
| 459 |
+
setIsWeekHidden(!!json?.week?.hidden);
|
| 460 |
+
} catch (e) { /* noop */ }
|
| 461 |
+
};
|
| 462 |
+
loadVisibility();
|
| 463 |
+
}, [selectedWeek]);
|
| 464 |
+
|
| 465 |
const handleFileUpload = async (file: File): Promise<string> => {
|
| 466 |
try {
|
| 467 |
setUploading(true);
|
|
|
|
| 1150 |
<div className="mt-2 flex items-center gap-2">
|
| 1151 |
<span className="text-xs text-ui-text/70">Visibility</span>
|
| 1152 |
<label className="switch">
|
| 1153 |
+
<input type="checkbox" checked={isWeekHidden} onChange={async(e)=>{
|
| 1154 |
try {
|
| 1155 |
const base = (((api.defaults as any)?.baseURL as string)||'').replace(/\/$/,'');
|
| 1156 |
const nextHidden = e.currentTarget.checked;
|
| 1157 |
await fetch(`${base}/api/admin/weeks/tutorial/${selectedWeek}/visibility`,{ method:'PUT', headers:{ 'Content-Type':'application/json', 'Authorization': localStorage.getItem('token')?`Bearer ${localStorage.getItem('token')}`:'', 'user-role':'admin' }, body: JSON.stringify({ hidden: nextHidden }) });
|
| 1158 |
+
setIsWeekHidden(nextHidden);
|
| 1159 |
await fetchTutorialTasks(true);
|
| 1160 |
} catch (err) { console.error(err);}
|
| 1161 |
}}/>
|
| 1162 |
<span className="slider" />
|
| 1163 |
</label>
|
| 1164 |
+
<span className="text-xs">{isWeekHidden ? 'Hidden' : 'Shown'}</span>
|
| 1165 |
</div>
|
| 1166 |
)}
|
| 1167 |
</div>
|
client/src/pages/WeeklyPractice.tsx
CHANGED
|
@@ -88,6 +88,7 @@ const WeeklyPractice: React.FC = () => {
|
|
| 88 |
const [isWeekTransitioning, setIsWeekTransitioning] = useState(false);
|
| 89 |
const [weeklyPractice, setWeeklyPractice] = useState<WeeklyPractice[]>([]);
|
| 90 |
const [weeklyPracticeWeek, setWeeklyPracticeWeek] = useState<WeeklyPracticeWeek | null>(null);
|
|
|
|
| 91 |
const [userSubmissions, setUserSubmissions] = useState<{[key: string]: UserSubmission[]}>({});
|
| 92 |
const [loading, setLoading] = useState(true);
|
| 93 |
const [submitting, setSubmitting] = useState<{[key: string]: boolean}>({});
|
|
@@ -160,6 +161,24 @@ const WeeklyPractice: React.FC = () => {
|
|
| 160 |
}, 0);
|
| 161 |
};
|
| 162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
const [editingPractice, setEditingPractice] = useState<string | null>(null);
|
| 164 |
const [editingBrief, setEditingBrief] = useState<{[key: number]: boolean}>({});
|
| 165 |
const [addingPractice, setAddingPractice] = useState<boolean>(false);
|
|
@@ -1463,18 +1482,19 @@ const WeeklyPractice: React.FC = () => {
|
|
| 1463 |
<div className="mt-2 flex items-center gap-2">
|
| 1464 |
<span className="text-xs text-ui-text/70">Visibility</span>
|
| 1465 |
<label className="switch">
|
| 1466 |
-
<input type="checkbox" checked={
|
| 1467 |
try {
|
| 1468 |
const base = (((api.defaults as any)?.baseURL as string)||'').replace(/\/$/,'');
|
| 1469 |
// when checked => Hidden, unchecked => Shown
|
| 1470 |
const nextHidden = e.currentTarget.checked;
|
| 1471 |
await fetch(`${base}/api/admin/weeks/weekly-practice/${selectedWeek}/visibility`,{ method:'PUT', headers:{ 'Content-Type':'application/json', 'Authorization': localStorage.getItem('token')?`Bearer ${localStorage.getItem('token')}`:'', 'user-role':'admin' }, body: JSON.stringify({ hidden: nextHidden }) });
|
|
|
|
| 1472 |
await fetchWeeklyPractice(true);
|
| 1473 |
} catch (err) { console.error(err);}
|
| 1474 |
}}/>
|
| 1475 |
<span className="slider" />
|
| 1476 |
</label>
|
| 1477 |
-
<span className="text-xs">{
|
| 1478 |
</div>
|
| 1479 |
)}
|
| 1480 |
</div>
|
|
|
|
| 88 |
const [isWeekTransitioning, setIsWeekTransitioning] = useState(false);
|
| 89 |
const [weeklyPractice, setWeeklyPractice] = useState<WeeklyPractice[]>([]);
|
| 90 |
const [weeklyPracticeWeek, setWeeklyPracticeWeek] = useState<WeeklyPracticeWeek | null>(null);
|
| 91 |
+
const [isWeekHidden, setIsWeekHidden] = useState<boolean>(false);
|
| 92 |
const [userSubmissions, setUserSubmissions] = useState<{[key: string]: UserSubmission[]}>({});
|
| 93 |
const [loading, setLoading] = useState(true);
|
| 94 |
const [submitting, setSubmitting] = useState<{[key: string]: boolean}>({});
|
|
|
|
| 161 |
}, 0);
|
| 162 |
};
|
| 163 |
|
| 164 |
+
// Fetch visibility for current week (admin use only)
|
| 165 |
+
useEffect(() => {
|
| 166 |
+
const loadVisibility = async () => {
|
| 167 |
+
try {
|
| 168 |
+
const base = (((api.defaults as any)?.baseURL as string) || '').replace(/\/$/, '');
|
| 169 |
+
const resp = await fetch(`${base}/api/admin/weeks/weekly-practice/${selectedWeek}/visibility`, {
|
| 170 |
+
headers: {
|
| 171 |
+
'Authorization': localStorage.getItem('token') ? `Bearer ${localStorage.getItem('token')}` : '',
|
| 172 |
+
'user-role': 'admin'
|
| 173 |
+
}
|
| 174 |
+
});
|
| 175 |
+
const json = await resp.json().catch(() => ({}));
|
| 176 |
+
setIsWeekHidden(!!json?.week?.hidden);
|
| 177 |
+
} catch (e) { /* noop */ }
|
| 178 |
+
};
|
| 179 |
+
loadVisibility();
|
| 180 |
+
}, [selectedWeek]);
|
| 181 |
+
|
| 182 |
const [editingPractice, setEditingPractice] = useState<string | null>(null);
|
| 183 |
const [editingBrief, setEditingBrief] = useState<{[key: number]: boolean}>({});
|
| 184 |
const [addingPractice, setAddingPractice] = useState<boolean>(false);
|
|
|
|
| 1482 |
<div className="mt-2 flex items-center gap-2">
|
| 1483 |
<span className="text-xs text-ui-text/70">Visibility</span>
|
| 1484 |
<label className="switch">
|
| 1485 |
+
<input type="checkbox" checked={isWeekHidden} onChange={async(e)=>{
|
| 1486 |
try {
|
| 1487 |
const base = (((api.defaults as any)?.baseURL as string)||'').replace(/\/$/,'');
|
| 1488 |
// when checked => Hidden, unchecked => Shown
|
| 1489 |
const nextHidden = e.currentTarget.checked;
|
| 1490 |
await fetch(`${base}/api/admin/weeks/weekly-practice/${selectedWeek}/visibility`,{ method:'PUT', headers:{ 'Content-Type':'application/json', 'Authorization': localStorage.getItem('token')?`Bearer ${localStorage.getItem('token')}`:'', 'user-role':'admin' }, body: JSON.stringify({ hidden: nextHidden }) });
|
| 1491 |
+
setIsWeekHidden(nextHidden);
|
| 1492 |
await fetchWeeklyPractice(true);
|
| 1493 |
} catch (err) { console.error(err);}
|
| 1494 |
}}/>
|
| 1495 |
<span className="slider" />
|
| 1496 |
</label>
|
| 1497 |
+
<span className="text-xs">{isWeekHidden ? 'Hidden' : 'Shown'}</span>
|
| 1498 |
</div>
|
| 1499 |
)}
|
| 1500 |
</div>
|