Compare commits
1 Commits
master
...
agent/g1-h
| Author | SHA1 | Date | |
|---|---|---|---|
| 34ea1e3f08 |
@ -39,6 +39,7 @@ interface LessonPlan {
|
|||||||
year_group: string | null;
|
year_group: string | null;
|
||||||
duration_minutes: number | null;
|
duration_minutes: number | null;
|
||||||
context_notes: string | null;
|
context_notes: string | null;
|
||||||
|
homework: string | null;
|
||||||
objectives: Objective[];
|
objectives: Objective[];
|
||||||
activities: Activity[];
|
activities: Activity[];
|
||||||
is_public: boolean;
|
is_public: boolean;
|
||||||
@ -88,6 +89,7 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
const [yearGroup, setYearGroup] = useState('');
|
const [yearGroup, setYearGroup] = useState('');
|
||||||
const [duration, setDuration] = useState('');
|
const [duration, setDuration] = useState('');
|
||||||
const [contextNotes, setContextNotes] = useState('');
|
const [contextNotes, setContextNotes] = useState('');
|
||||||
|
const [homework, setHomework] = useState('');
|
||||||
const [isPublic, setIsPublic] = useState(false);
|
const [isPublic, setIsPublic] = useState(false);
|
||||||
const [objectives, setObjectives] = useState<Objective[]>([]);
|
const [objectives, setObjectives] = useState<Objective[]>([]);
|
||||||
const [activities, setActivities] = useState<Activity[]>([]);
|
const [activities, setActivities] = useState<Activity[]>([]);
|
||||||
@ -110,6 +112,7 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
setYearGroup(data.year_group || '');
|
setYearGroup(data.year_group || '');
|
||||||
setDuration(data.duration_minutes?.toString() || '');
|
setDuration(data.duration_minutes?.toString() || '');
|
||||||
setContextNotes(data.context_notes || '');
|
setContextNotes(data.context_notes || '');
|
||||||
|
setHomework(data.homework || '');
|
||||||
setIsPublic(data.is_public || false);
|
setIsPublic(data.is_public || false);
|
||||||
setObjectives(data.objectives || []);
|
setObjectives(data.objectives || []);
|
||||||
setActivities(data.activities || []);
|
setActivities(data.activities || []);
|
||||||
@ -128,7 +131,7 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
// ── Save ──────────────────────────────────────────────────────────────────
|
// ── Save ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const save = useCallback(async (
|
const save = useCallback(async (
|
||||||
overrides?: Partial<{ title: string; subject: string; year_group: string; duration_minutes: number | null; context_notes: string; is_public: boolean; objectives: Objective[]; activities: Activity[] }>
|
overrides?: Partial<{ title: string; subject: string; year_group: string; duration_minutes: number | null; context_notes: string; homework: string; is_public: boolean; objectives: Objective[]; activities: Activity[] }>
|
||||||
) => {
|
) => {
|
||||||
if (!accessToken || !planId) return;
|
if (!accessToken || !planId) return;
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
@ -143,6 +146,7 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
year_group: yearGroup || null,
|
year_group: yearGroup || null,
|
||||||
duration_minutes: duration ? parseInt(duration, 10) : null,
|
duration_minutes: duration ? parseInt(duration, 10) : null,
|
||||||
context_notes: contextNotes || null,
|
context_notes: contextNotes || null,
|
||||||
|
homework: homework || '',
|
||||||
is_public: isPublic,
|
is_public: isPublic,
|
||||||
objectives,
|
objectives,
|
||||||
activities,
|
activities,
|
||||||
@ -156,7 +160,7 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
} finally {
|
} finally {
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
}
|
}
|
||||||
}, [accessToken, planId, title, subject, yearGroup, duration, contextNotes, isPublic, objectives, activities]);
|
}, [accessToken, planId, title, subject, yearGroup, duration, contextNotes, homework, isPublic, objectives, activities]);
|
||||||
|
|
||||||
const scheduleAutoSave = useCallback(() => {
|
const scheduleAutoSave = useCallback(() => {
|
||||||
if (autoSaveTimer.current) clearTimeout(autoSaveTimer.current);
|
if (autoSaveTimer.current) clearTimeout(autoSaveTimer.current);
|
||||||
@ -359,6 +363,22 @@ const LessonPlanDetailPage: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Homework */}
|
||||||
|
<Box sx={{ mb: 3 }}>
|
||||||
|
<Typography variant="subtitle2" fontWeight={600} sx={{ mb: 0.75 }}>
|
||||||
|
Homework
|
||||||
|
</Typography>
|
||||||
|
<TextField
|
||||||
|
value={homework}
|
||||||
|
onChange={e => { setHomework(e.target.value); scheduleAutoSave(); }}
|
||||||
|
multiline
|
||||||
|
minRows={2}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
placeholder="Homework to carry with this plan when assigned to a taught lesson…"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Divider sx={{ mb: 3 }} />
|
<Divider sx={{ mb: 3 }} />
|
||||||
|
|
||||||
{/* Objectives */}
|
{/* Objectives */}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ interface PlanSummary {
|
|||||||
duration_minutes: number | null;
|
duration_minutes: number | null;
|
||||||
objectives: { id: string; text: string; bloom_level?: string }[];
|
objectives: { id: string; text: string; bloom_level?: string }[];
|
||||||
activities: { id: string; section: string; title: string }[];
|
activities: { id: string; section: string; title: string }[];
|
||||||
|
homework: string | null;
|
||||||
is_public: boolean;
|
is_public: boolean;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
@ -144,6 +145,7 @@ function PlanCard({ plan, onOpen, onDelete }: {
|
|||||||
</Box>
|
</Box>
|
||||||
<Typography variant="caption" color="text.secondary">
|
<Typography variant="caption" color="text.secondary">
|
||||||
{objCount} objective{objCount !== 1 ? 's' : ''} · {actCount} activit{actCount !== 1 ? 'ies' : 'y'}
|
{objCount} objective{objCount !== 1 ? 's' : ''} · {actCount} activit{actCount !== 1 ? 'ies' : 'y'}
|
||||||
|
{plan.homework ? ' · homework set' : ''}
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardActions sx={{ pt: 0, px: 1.5, pb: 1.5, justifyContent: 'flex-end' }} onClick={e => e.stopPropagation()}>
|
<CardActions sx={{ pt: 0, px: 1.5, pb: 1.5, justifyContent: 'flex-end' }} onClick={e => e.stopPropagation()}>
|
||||||
|
|||||||
@ -22,6 +22,7 @@ interface Lesson {
|
|||||||
week_cycle: string;
|
week_cycle: string;
|
||||||
day_of_week: string;
|
day_of_week: string;
|
||||||
status: string;
|
status: string;
|
||||||
|
homework: string | null;
|
||||||
teacher_name: string | null;
|
teacher_name: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +96,11 @@ function LessonCard({ lesson }: { lesson: Lesson }) {
|
|||||||
sx={{ height: 16, fontSize: '0.65rem' }}
|
sx={{ height: 16, fontSize: '0.65rem' }}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
{lesson.homework && (
|
||||||
|
<Typography variant="caption" sx={{ color: 'primary.main', fontSize: '0.68rem', fontWeight: 600 }}>
|
||||||
|
Homework: {lesson.homework.length > 80 ? lesson.homework.slice(0, 80) + '…' : lesson.homework}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
{lesson.teacher_name && (
|
{lesson.teacher_name && (
|
||||||
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.68rem' }}>
|
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.68rem' }}>
|
||||||
{lesson.teacher_name}
|
{lesson.teacher_name}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ interface Lesson {
|
|||||||
day_of_week: string;
|
day_of_week: string;
|
||||||
status: string;
|
status: string;
|
||||||
lesson_plan: Record<string, any>;
|
lesson_plan: Record<string, any>;
|
||||||
|
homework: string | null;
|
||||||
notes: string | null;
|
notes: string | null;
|
||||||
whiteboard_room_id: string | null;
|
whiteboard_room_id: string | null;
|
||||||
}
|
}
|
||||||
@ -76,16 +77,18 @@ const STATUS_COLORS: Record<string, 'default' | 'primary' | 'success' | 'error'
|
|||||||
interface EditDialogProps {
|
interface EditDialogProps {
|
||||||
lesson: Lesson | null;
|
lesson: Lesson | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSave: (id: string, updates: { notes?: string; status?: string }) => Promise<void>;
|
onSave: (id: string, updates: { homework?: string; notes?: string; status?: string }) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function LessonEditDialog({ lesson, onClose, onSave }: EditDialogProps) {
|
function LessonEditDialog({ lesson, onClose, onSave }: EditDialogProps) {
|
||||||
|
const [homework, setHomework] = useState('');
|
||||||
const [notes, setNotes] = useState('');
|
const [notes, setNotes] = useState('');
|
||||||
const [status, setStatus] = useState('planned');
|
const [status, setStatus] = useState('planned');
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (lesson) {
|
if (lesson) {
|
||||||
|
setHomework(lesson.homework || '');
|
||||||
setNotes(lesson.notes || '');
|
setNotes(lesson.notes || '');
|
||||||
setStatus(lesson.status || 'planned');
|
setStatus(lesson.status || 'planned');
|
||||||
}
|
}
|
||||||
@ -94,7 +97,7 @@ function LessonEditDialog({ lesson, onClose, onSave }: EditDialogProps) {
|
|||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (!lesson) return;
|
if (!lesson) return;
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
await onSave(lesson.id, { notes, status });
|
await onSave(lesson.id, { homework, notes, status });
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
onClose();
|
onClose();
|
||||||
};
|
};
|
||||||
@ -127,6 +130,16 @@ function LessonEditDialog({ lesson, onClose, onSave }: EditDialogProps) {
|
|||||||
<MenuItem value="substituted">Substituted</MenuItem>
|
<MenuItem value="substituted">Substituted</MenuItem>
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<TextField
|
||||||
|
label="Homework"
|
||||||
|
value={homework}
|
||||||
|
onChange={e => setHomework(e.target.value)}
|
||||||
|
multiline
|
||||||
|
minRows={2}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
placeholder="Homework for this lesson…"
|
||||||
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label="Notes"
|
label="Notes"
|
||||||
value={notes}
|
value={notes}
|
||||||
@ -209,6 +222,11 @@ function LessonCard({ lesson, onEdit, onAssignPlan }: LessonCardProps) {
|
|||||||
sx={{ height: 16, fontSize: '0.65rem' }}
|
sx={{ height: 16, fontSize: '0.65rem' }}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
{lesson.homework && (
|
||||||
|
<Typography variant="caption" sx={{ color: 'primary.main', fontSize: '0.68rem', fontWeight: 600, mt: 0.25 }}>
|
||||||
|
Homework: {lesson.homework.length > 80 ? lesson.homework.slice(0, 80) + '…' : lesson.homework}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
{lesson.notes && (
|
{lesson.notes && (
|
||||||
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.68rem', fontStyle: 'italic', mt: 0.25 }}>
|
<Typography variant="caption" sx={{ color: 'text.secondary', fontSize: '0.68rem', fontStyle: 'italic', mt: 0.25 }}>
|
||||||
{lesson.notes.length > 80 ? lesson.notes.slice(0, 80) + '…' : lesson.notes}
|
{lesson.notes.length > 80 ? lesson.notes.slice(0, 80) + '…' : lesson.notes}
|
||||||
@ -287,7 +305,7 @@ const TaughtLessonsPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveLesson = async (id: string, updates: { notes?: string; status?: string }) => {
|
const handleSaveLesson = async (id: string, updates: { homework?: string; notes?: string; status?: string }) => {
|
||||||
if (!accessToken) return;
|
if (!accessToken) return;
|
||||||
await fetch(`${API_BASE}/timetable/lessons/${id}`, {
|
await fetch(`${API_BASE}/timetable/lessons/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
|
|||||||
@ -86,6 +86,12 @@ export class CCPlannedLessonNodeShapeUtil extends CCBaseShapeUtil<CCPlannedLesso
|
|||||||
labelStyle={styles.property.label}
|
labelStyle={styles.property.label}
|
||||||
valueStyle={styles.property.value}
|
valueStyle={styles.property.value}
|
||||||
/>
|
/>
|
||||||
|
<NodeProperty
|
||||||
|
label="Homework"
|
||||||
|
value={shape.props.homework}
|
||||||
|
labelStyle={styles.property.label}
|
||||||
|
valueStyle={styles.property.value}
|
||||||
|
/>
|
||||||
<NodeProperty
|
<NodeProperty
|
||||||
label="Topic Code"
|
label="Topic Code"
|
||||||
value={shape.props.topic_code}
|
value={shape.props.topic_code}
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import { CCGraphShape, GraphShapeType } from './cc-graph-types'
|
|||||||
// Helper function to create version IDs for a shape type
|
// Helper function to create version IDs for a shape type
|
||||||
const createVersions = (shapeType: GraphShapeType) => {
|
const createVersions = (shapeType: GraphShapeType) => {
|
||||||
return createShapePropsMigrationIds(shapeType, {
|
return createShapePropsMigrationIds(shapeType, {
|
||||||
Initial: 1 // All shapes start at version 1 as required by TLDraw
|
Initial: 1, // All shapes start at version 1 as required by TLDraw
|
||||||
|
AddPlannedLessonHomework: 2,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,6 +22,13 @@ const createMigrationSequence = (shapeType: GraphShapeType) => {
|
|||||||
return props
|
return props
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
...(shapeType === 'cc-planned-lesson-node' ? [{
|
||||||
|
id: versions.AddPlannedLessonHomework,
|
||||||
|
up: (props: CCGraphShape['props']) => ({
|
||||||
|
homework: '',
|
||||||
|
...props,
|
||||||
|
}),
|
||||||
|
}] : []),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -199,6 +199,7 @@ export const ccGraphShapeProps = {
|
|||||||
subject: T.string,
|
subject: T.string,
|
||||||
teacher_code: T.string,
|
teacher_code: T.string,
|
||||||
planning_status: T.string,
|
planning_status: T.string,
|
||||||
|
homework: T.string,
|
||||||
topic_code: T.string,
|
topic_code: T.string,
|
||||||
topic_name: T.string,
|
topic_name: T.string,
|
||||||
lesson_code: T.string,
|
lesson_code: T.string,
|
||||||
@ -560,6 +561,7 @@ export const getDefaultCCPlannedLessonNodeProps = () => ({
|
|||||||
subject: '',
|
subject: '',
|
||||||
teacher_code: '',
|
teacher_code: '',
|
||||||
planning_status: '',
|
planning_status: '',
|
||||||
|
homework: '',
|
||||||
topic_code: '',
|
topic_code: '',
|
||||||
topic_name: '',
|
topic_name: '',
|
||||||
lesson_code: '',
|
lesson_code: '',
|
||||||
|
|||||||
@ -204,6 +204,7 @@ export type CCPlannedLessonNodeProps = CCGraphShapeProps & {
|
|||||||
subject: string
|
subject: string
|
||||||
teacher_code: string
|
teacher_code: string
|
||||||
planning_status: string
|
planning_status: string
|
||||||
|
homework: string
|
||||||
topic_code: string
|
topic_code: string
|
||||||
topic_name: string
|
topic_name: string
|
||||||
lesson_code: string
|
lesson_code: string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user