Tighten typing and input validation across study pages
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m2s
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m2s
This commit is contained in:
parent
6d1d918355
commit
d6f3502cb1
16 changed files with 170 additions and 56 deletions
|
|
@ -27,6 +27,7 @@ import {
|
|||
useSortable,
|
||||
} from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import type { ReorderItem } from "@/types/study";
|
||||
|
||||
interface DeckItem {
|
||||
id: string;
|
||||
|
|
@ -65,7 +66,14 @@ function getProgressLabel(deck: DeckItem) {
|
|||
return `${current}/${total}, ${modeLabel} · ${correctCount} ✓`;
|
||||
}
|
||||
|
||||
function SortableDeckCard({ deck, onEdit, onDelete, classSlug }: any) {
|
||||
interface SortableDeckCardProps {
|
||||
deck: DeckItem;
|
||||
onEdit: (deck: DeckItem) => void;
|
||||
onDelete: (deck: DeckItem) => void;
|
||||
classSlug: string;
|
||||
}
|
||||
|
||||
function SortableDeckCard({ deck, onEdit, onDelete, classSlug }: SortableDeckCardProps) {
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: deck.id });
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
|
|
@ -314,8 +322,6 @@ export default function FlashcardsPage() {
|
|||
if (!activeDeck) return;
|
||||
|
||||
let targetGroupId: string | null = null;
|
||||
let targetIndex = 0;
|
||||
|
||||
const overContainerId = over.data.current?.sortable?.containerId;
|
||||
if (overContainerId) {
|
||||
targetGroupId = overContainerId === "uncategorized" ? null : overContainerId;
|
||||
|
|
@ -344,7 +350,7 @@ export default function FlashcardsPage() {
|
|||
}
|
||||
|
||||
const affectedGroups = new Set([activeDeck.groupId, targetGroupId]);
|
||||
const updates: any[] = [];
|
||||
const updates: ReorderItem[] = [];
|
||||
|
||||
affectedGroups.forEach(gId => {
|
||||
const gItems = newItems.filter(d => d.groupId === gId);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import {
|
|||
useSortable,
|
||||
} from "@dnd-kit/sortable";
|
||||
import { CSS } from "@dnd-kit/utilities";
|
||||
import type { ReorderItem } from "@/types/study";
|
||||
|
||||
interface QuizItem {
|
||||
id: string;
|
||||
|
|
@ -51,7 +52,14 @@ interface MaterialGroup {
|
|||
|
||||
const cache: Record<string, { quizzes: QuizItem[]; groups: MaterialGroup[] }> = {};
|
||||
|
||||
function SortableQuizCard({ quiz, onEdit, onDelete, classSlug }: any) {
|
||||
interface SortableQuizCardProps {
|
||||
quiz: QuizItem;
|
||||
onEdit: (quiz: QuizItem) => void;
|
||||
onDelete: (quiz: QuizItem) => void;
|
||||
classSlug: string;
|
||||
}
|
||||
|
||||
function SortableQuizCard({ quiz, onEdit, onDelete, classSlug }: SortableQuizCardProps) {
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: quiz.id });
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
|
|
@ -312,8 +320,6 @@ export default function QuizzesPage() {
|
|||
if (!activeQuiz) return;
|
||||
|
||||
let targetGroupId: string | null = null;
|
||||
let targetIndex = 0;
|
||||
|
||||
// Check if over a group container directly
|
||||
const overContainerId = over.data.current?.sortable?.containerId;
|
||||
if (overContainerId) {
|
||||
|
|
@ -345,7 +351,7 @@ export default function QuizzesPage() {
|
|||
|
||||
// Re-calculate sortOrder for the affected groups to persist
|
||||
const affectedGroups = new Set([activeQuiz.groupId, targetGroupId]);
|
||||
const updates: any[] = [];
|
||||
const updates: ReorderItem[] = [];
|
||||
|
||||
affectedGroups.forEach(gId => {
|
||||
const gItems = newItems.filter(q => q.groupId === gId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue