Archived
feat: US #32 Section-based Reading Recommendations
Backend: - Add ReadingSchedule and MeetingSection models for ebook reading schedules - Implement recommendation algorithm: greedy partition minimizing per-meeting time variance - Algorithm respects chapter boundaries, estimates time based on chapter weight - Add serializers for schedules (list/detail/generate/confirm/update) - Add ScheduleViewSet with endpoints: list, create (generate), retrieve, regenerate, confirm, update_meeting, reorder_meetings - Add URL routes for /api/books/schedules/ - Create migration 0004 for new models Frontend: - Add types: MeetingSection, ReadingSchedule, GenerateRecommendationsRequest - Add schedulesApi with methods: getSchedules, generateRecommendations, confirmSchedule, updateMeeting, reorderMeetings, deleteSchedule - Build RecommendationPage with 4-column meeting layout, drag-and-drop chapter reassignment, generate/regenerate/confirm flow - Add 'Schedule Reading' menu item to BookContextMenu - Add route: /books/:ebookId/schedule
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18n-lite";
|
||||
import { booksApi } from "../api/books";
|
||||
import { getApiErrorMessage } from "../api/errors";
|
||||
@@ -46,6 +47,7 @@ export function BookContextMenu({
|
||||
const { t, language } = useTranslation();
|
||||
const locale = language as SupportedLanguage;
|
||||
const { showToast } = useToast();
|
||||
const navigate = useNavigate();
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
const [position, setPosition] = useState({ left: x, top: y });
|
||||
const [activeAction, setActiveAction] = useState<ActionKind>(null);
|
||||
@@ -148,6 +150,18 @@ export function BookContextMenu({
|
||||
>
|
||||
{activeAction === "sync" ? t("contextMenu.syncingMetadata") : t("contextMenu.syncMetadata")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.item}
|
||||
role="menuitem"
|
||||
disabled={busy}
|
||||
onClick={() => {
|
||||
navigate(`/books/${book.id}/schedule`);
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
📅 Schedule Reading
|
||||
</button>
|
||||
<div className={styles.separator} role="separator" />
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user