feat(flashcards): фаза 1 полировки — хоткеи, поиск, drag-reorder, честные интервалы
- study: хоткеи Space/стрелки=флип, 1-4/←→=оценка - превью интервалов = точная копия серверного SM-2 (было враньё «<1 мин») - поиск/фильтр карточек внутри колоды - drag-reorder карточек + endpoint PUT /decks/:id/reorder (requireOwnership) - flashcard_decks добавлен в ALLOWED_TABLES requireOwnership - эмодзи в empty-state → inline SVG .ic - deleteCard: нативный confirm() → LS.confirm Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -126,6 +126,30 @@ function addCardsBulk(req, res) {
|
||||
res.json({ inserted });
|
||||
}
|
||||
|
||||
/* ── PUT /api/flashcards/decks/:id/reorder ─────────────────────────────────
|
||||
body: { order: [cardId, …] } — переписывает order_idx по позиции в массиве.
|
||||
Принимаются только карточки, реально принадлежащие колоде владельца. */
|
||||
function reorderCards(req, res) {
|
||||
const uid = req.user.id;
|
||||
const deck = db.prepare(`SELECT id FROM flashcard_decks WHERE id = ? AND user_id = ?`)
|
||||
.get(req.params.id, uid);
|
||||
if (!deck) return res.status(404).json({ error: 'Not found' });
|
||||
const { order } = req.body;
|
||||
if (!Array.isArray(order) || !order.length)
|
||||
return res.status(400).json({ error: 'order[] required' });
|
||||
|
||||
const owned = new Set(
|
||||
db.prepare(`SELECT id FROM flashcard_cards WHERE deck_id = ?`).all(deck.id).map(r => r.id)
|
||||
);
|
||||
const stmt = db.prepare(`UPDATE flashcard_cards SET order_idx = ? WHERE id = ? AND deck_id = ?`);
|
||||
const run = db.transaction(() => {
|
||||
let idx = 0;
|
||||
order.forEach(id => { if (owned.has(Number(id))) stmt.run(idx++, Number(id), deck.id); });
|
||||
});
|
||||
run();
|
||||
res.json({ ok: true });
|
||||
}
|
||||
|
||||
/* ── PUT /api/flashcards/cards/:id ─────────────────────────────────────── */
|
||||
function updateCard(req, res) {
|
||||
const uid = req.user.id;
|
||||
@@ -298,7 +322,7 @@ function getRandom(req, res) {
|
||||
|
||||
module.exports = {
|
||||
listDecks, createDeck, updateDeck, deleteDeck,
|
||||
getCards, addCard, addCardsBulk, updateCard, deleteCard,
|
||||
getCards, addCard, addCardsBulk, updateCard, deleteCard, reorderCards,
|
||||
getStudySession, submitReview, getStats,
|
||||
quickAdd, getRandom,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user