@oaknational/google-classroom-addon 1.22.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import * as _googleapis_classroom from '@googleapis/classroom';
1
2
  import { Firestore } from '@google-cloud/firestore';
2
3
  import z from 'zod';
3
4
 
@@ -39,10 +40,148 @@ declare const createAnnouncementAttachmentArgsSchema: z.ZodObject<{
39
40
  }, z.core.$strip>;
40
41
  type CreateAnnouncementAttachmentArgs = z.infer<typeof createAnnouncementAttachmentArgsSchema>;
41
42
 
43
+ declare const pupilLessonProgressSchema: z.ZodObject<{
44
+ submissionId: z.ZodString;
45
+ attachmentId: z.ZodString;
46
+ courseId: z.ZodString;
47
+ itemId: z.ZodString;
48
+ pupilLoginHint: z.ZodString;
49
+ starterQuiz: z.ZodOptional<z.ZodObject<{
50
+ grade: z.ZodNumber;
51
+ numQuestions: z.ZodNumber;
52
+ isComplete: z.ZodBoolean;
53
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
54
+ mode: z.ZodEnum<{
55
+ init: "init";
56
+ incomplete: "incomplete";
57
+ input: "input";
58
+ grading: "grading";
59
+ feedback: "feedback";
60
+ }>;
61
+ grade: z.ZodNumber;
62
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
63
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
64
+ correct: "correct";
65
+ incorrect: "incorrect";
66
+ }>, z.ZodArray<z.ZodEnum<{
67
+ correct: "correct";
68
+ incorrect: "incorrect";
69
+ }>>]>>;
70
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
71
+ }, z.core.$strip>>>;
72
+ }, z.core.$strip>>;
73
+ exitQuiz: z.ZodOptional<z.ZodObject<{
74
+ grade: z.ZodNumber;
75
+ numQuestions: z.ZodNumber;
76
+ isComplete: z.ZodBoolean;
77
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
78
+ mode: z.ZodEnum<{
79
+ init: "init";
80
+ incomplete: "incomplete";
81
+ input: "input";
82
+ grading: "grading";
83
+ feedback: "feedback";
84
+ }>;
85
+ grade: z.ZodNumber;
86
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
87
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
88
+ correct: "correct";
89
+ incorrect: "incorrect";
90
+ }>, z.ZodArray<z.ZodEnum<{
91
+ correct: "correct";
92
+ incorrect: "incorrect";
93
+ }>>]>>;
94
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
95
+ }, z.core.$strip>>>;
96
+ }, z.core.$strip>>;
97
+ video: z.ZodOptional<z.ZodObject<{
98
+ played: z.ZodBoolean;
99
+ duration: z.ZodNumber;
100
+ timeElapsed: z.ZodNumber;
101
+ isComplete: z.ZodBoolean;
102
+ }, z.core.$strip>>;
103
+ intro: z.ZodOptional<z.ZodObject<{
104
+ worksheetAvailable: z.ZodOptional<z.ZodBoolean>;
105
+ worksheetDownloaded: z.ZodOptional<z.ZodBoolean>;
106
+ isComplete: z.ZodBoolean;
107
+ }, z.core.$strip>>;
108
+ updatedAt: z.ZodString;
109
+ createdAt: z.ZodString;
110
+ }, z.core.$strip>;
111
+ type PupilLessonProgress = z.infer<typeof pupilLessonProgressSchema>;
112
+ declare const upsertPupilLessonProgressArgsSchema: z.ZodObject<{
113
+ submissionId: z.ZodString;
114
+ attachmentId: z.ZodString;
115
+ courseId: z.ZodString;
116
+ itemId: z.ZodString;
117
+ pupilLoginHint: z.ZodString;
118
+ starterQuiz: z.ZodOptional<z.ZodObject<{
119
+ grade: z.ZodNumber;
120
+ numQuestions: z.ZodNumber;
121
+ isComplete: z.ZodBoolean;
122
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
123
+ mode: z.ZodEnum<{
124
+ init: "init";
125
+ incomplete: "incomplete";
126
+ input: "input";
127
+ grading: "grading";
128
+ feedback: "feedback";
129
+ }>;
130
+ grade: z.ZodNumber;
131
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
132
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
133
+ correct: "correct";
134
+ incorrect: "incorrect";
135
+ }>, z.ZodArray<z.ZodEnum<{
136
+ correct: "correct";
137
+ incorrect: "incorrect";
138
+ }>>]>>;
139
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
140
+ }, z.core.$strip>>>;
141
+ }, z.core.$strip>>;
142
+ exitQuiz: z.ZodOptional<z.ZodObject<{
143
+ grade: z.ZodNumber;
144
+ numQuestions: z.ZodNumber;
145
+ isComplete: z.ZodBoolean;
146
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
147
+ mode: z.ZodEnum<{
148
+ init: "init";
149
+ incomplete: "incomplete";
150
+ input: "input";
151
+ grading: "grading";
152
+ feedback: "feedback";
153
+ }>;
154
+ grade: z.ZodNumber;
155
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
156
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
157
+ correct: "correct";
158
+ incorrect: "incorrect";
159
+ }>, z.ZodArray<z.ZodEnum<{
160
+ correct: "correct";
161
+ incorrect: "incorrect";
162
+ }>>]>>;
163
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
164
+ }, z.core.$strip>>>;
165
+ }, z.core.$strip>>;
166
+ video: z.ZodOptional<z.ZodObject<{
167
+ played: z.ZodBoolean;
168
+ duration: z.ZodNumber;
169
+ timeElapsed: z.ZodNumber;
170
+ isComplete: z.ZodBoolean;
171
+ }, z.core.$strip>>;
172
+ intro: z.ZodOptional<z.ZodObject<{
173
+ worksheetAvailable: z.ZodOptional<z.ZodBoolean>;
174
+ worksheetDownloaded: z.ZodOptional<z.ZodBoolean>;
175
+ isComplete: z.ZodBoolean;
176
+ }, z.core.$strip>>;
177
+ }, z.core.$strip>;
178
+ type UpsertPupilLessonProgressArgs = z.infer<typeof upsertPupilLessonProgressArgsSchema>;
179
+
42
180
  type VerifiedAuthSession = {
43
181
  session: string;
44
182
  token: string;
45
183
  userProfilePicUrl?: string;
184
+ loginHint?: string;
46
185
  };
47
186
  type OakGoogleSignInCallback = {
48
187
  encryptedSession: string;
@@ -53,6 +192,9 @@ declare class OakGoogleClassroomAddOn {
53
192
  private oauthService;
54
193
  private sessionService;
55
194
  private classroomAttachmentService;
195
+ private pupilProgressService;
196
+ private encryptionService;
197
+ private firestoreClient;
56
198
  constructor(encryptionSecret: string, firestore: Firestore, googleOAuthClientId: string, googleOAuthClientSecret: string, googleOAuthCallbackApiRoute: string, sessionSecret: string, baseUrl: string);
57
199
  /**
58
200
  * Generates the Google OAuth sign-in URL for user authentication.
@@ -90,6 +232,47 @@ declare class OakGoogleClassroomAddOn {
90
232
  * @param session - The user's encrypted session string
91
233
  */
92
234
  createAttachment(args: CreateAnnouncementAttachmentArgs, accessToken: string, session: string): Promise<ClassroomAttachmentEntity | null>;
235
+ /**
236
+ * Gets the add-on context from Google Classroom for the current pupil.
237
+ * Returns the studentContext including submissionId, plus the pupilLoginHint
238
+ * extracted from the session.
239
+ * @param courseId - The Google Classroom course ID
240
+ * @param itemId - The courseWork item ID
241
+ * @param attachmentId - The attachment ID
242
+ * @param accessToken - The pupil's current OAuth access token
243
+ * @param session - The pupil's encrypted session string
244
+ */
245
+ getAddOnContext(courseId: string, itemId: string, attachmentId: string, accessToken: string, session: string): Promise<{
246
+ pupilLoginHint: string;
247
+ courseId?: string | null;
248
+ itemId?: string | null;
249
+ postId?: string | null;
250
+ studentContext?: _googleapis_classroom.classroom_v1.Schema$StudentContext;
251
+ supportsStudentWork?: boolean | null;
252
+ teacherContext?: _googleapis_classroom.classroom_v1.Schema$TeacherContext;
253
+ }>;
254
+ /**
255
+ * Resolves a teacher OAuth client by looking up the attachment's teacherLoginHint
256
+ * and fetching the teacher's stored credentials from Firestore.
257
+ * In dev mode, falls back to GOOGLE_CLASSROOM_DEV_REFRESH_TOKEN if teacher credentials are not found.
258
+ * @param attachmentId - The attachment ID to look up the teacher for.
259
+ * @returns A GoogleOAuthClient authenticated with teacher credentials, or undefined if unavailable.
260
+ */
261
+ private resolveTeacherOAuthClient;
262
+ /**
263
+ * Upserts pupil lesson progress to Firestore and updates GC pointsEarned
264
+ * when the exit quiz is newly completed, using the teacher's OAuth credentials.
265
+ * @param args - The lesson progress data
266
+ * @param accessToken - The pupil's current OAuth access token
267
+ * @param session - The pupil's encrypted session string
268
+ */
269
+ upsertPupilLessonProgress(args: UpsertPupilLessonProgressArgs, accessToken: string, session: string): Promise<PupilLessonProgress>;
270
+ /**
271
+ * Retrieves pupil lesson progress from Firestore.
272
+ * Does not require Google Classroom authentication.
273
+ * @param submissionId - The Google Classroom submission ID
274
+ */
275
+ getPupilLessonProgress(submissionId: string): Promise<PupilLessonProgress | null>;
93
276
  }
94
277
 
95
278
  declare enum ExceptionType {
package/dist/types.d.ts CHANGED
@@ -86,5 +86,198 @@ declare const classroomAttachmentSchema: z.ZodObject<{
86
86
  }, z.core.$strip>;
87
87
  type ClassroomAttachment = z.infer<typeof classroomAttachmentSchema>;
88
88
 
89
- export { CreateAttachmentCallSchema, classroomAttachmentEntitySchema, classroomAttachmentSchema, codeSchema, createAnnouncementAttachmentArgsSchema, googleOAuthUserSchema, tokenPayloadSchema, userCredentialsEntitySchema };
90
- export type { ClassroomAttachment, ClassroomAttachmentEntity, Code, CreateAnnouncementAttachmentArgs, CreateAttachmentCall, GoogleOAuthUser, TokenPayload, UserCredentialsEntity };
89
+ declare const UPDATABLE_SUBMISSION_STATES: readonly ["NEW", "CREATED", "RECLAIMED_BY_STUDENT"];
90
+ type UpdatableSubmissionState = (typeof UPDATABLE_SUBMISSION_STATES)[number];
91
+ declare const questionResultSchema: z.ZodObject<{
92
+ mode: z.ZodEnum<{
93
+ init: "init";
94
+ incomplete: "incomplete";
95
+ input: "input";
96
+ grading: "grading";
97
+ feedback: "feedback";
98
+ }>;
99
+ grade: z.ZodNumber;
100
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
101
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
102
+ correct: "correct";
103
+ incorrect: "incorrect";
104
+ }>, z.ZodArray<z.ZodEnum<{
105
+ correct: "correct";
106
+ incorrect: "incorrect";
107
+ }>>]>>;
108
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
109
+ }, z.core.$strip>;
110
+ declare const quizProgressSchema: z.ZodObject<{
111
+ grade: z.ZodNumber;
112
+ numQuestions: z.ZodNumber;
113
+ isComplete: z.ZodBoolean;
114
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
115
+ mode: z.ZodEnum<{
116
+ init: "init";
117
+ incomplete: "incomplete";
118
+ input: "input";
119
+ grading: "grading";
120
+ feedback: "feedback";
121
+ }>;
122
+ grade: z.ZodNumber;
123
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
124
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
125
+ correct: "correct";
126
+ incorrect: "incorrect";
127
+ }>, z.ZodArray<z.ZodEnum<{
128
+ correct: "correct";
129
+ incorrect: "incorrect";
130
+ }>>]>>;
131
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
132
+ }, z.core.$strip>>>;
133
+ }, z.core.$strip>;
134
+ declare const videoProgressSchema: z.ZodObject<{
135
+ played: z.ZodBoolean;
136
+ duration: z.ZodNumber;
137
+ timeElapsed: z.ZodNumber;
138
+ isComplete: z.ZodBoolean;
139
+ }, z.core.$strip>;
140
+ declare const introProgressSchema: z.ZodObject<{
141
+ worksheetAvailable: z.ZodOptional<z.ZodBoolean>;
142
+ worksheetDownloaded: z.ZodOptional<z.ZodBoolean>;
143
+ isComplete: z.ZodBoolean;
144
+ }, z.core.$strip>;
145
+ declare const pupilLessonProgressSchema: z.ZodObject<{
146
+ submissionId: z.ZodString;
147
+ attachmentId: z.ZodString;
148
+ courseId: z.ZodString;
149
+ itemId: z.ZodString;
150
+ pupilLoginHint: z.ZodString;
151
+ starterQuiz: z.ZodOptional<z.ZodObject<{
152
+ grade: z.ZodNumber;
153
+ numQuestions: z.ZodNumber;
154
+ isComplete: z.ZodBoolean;
155
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
156
+ mode: z.ZodEnum<{
157
+ init: "init";
158
+ incomplete: "incomplete";
159
+ input: "input";
160
+ grading: "grading";
161
+ feedback: "feedback";
162
+ }>;
163
+ grade: z.ZodNumber;
164
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
165
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
166
+ correct: "correct";
167
+ incorrect: "incorrect";
168
+ }>, z.ZodArray<z.ZodEnum<{
169
+ correct: "correct";
170
+ incorrect: "incorrect";
171
+ }>>]>>;
172
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
173
+ }, z.core.$strip>>>;
174
+ }, z.core.$strip>>;
175
+ exitQuiz: z.ZodOptional<z.ZodObject<{
176
+ grade: z.ZodNumber;
177
+ numQuestions: z.ZodNumber;
178
+ isComplete: z.ZodBoolean;
179
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
180
+ mode: z.ZodEnum<{
181
+ init: "init";
182
+ incomplete: "incomplete";
183
+ input: "input";
184
+ grading: "grading";
185
+ feedback: "feedback";
186
+ }>;
187
+ grade: z.ZodNumber;
188
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
189
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
190
+ correct: "correct";
191
+ incorrect: "incorrect";
192
+ }>, z.ZodArray<z.ZodEnum<{
193
+ correct: "correct";
194
+ incorrect: "incorrect";
195
+ }>>]>>;
196
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
197
+ }, z.core.$strip>>>;
198
+ }, z.core.$strip>>;
199
+ video: z.ZodOptional<z.ZodObject<{
200
+ played: z.ZodBoolean;
201
+ duration: z.ZodNumber;
202
+ timeElapsed: z.ZodNumber;
203
+ isComplete: z.ZodBoolean;
204
+ }, z.core.$strip>>;
205
+ intro: z.ZodOptional<z.ZodObject<{
206
+ worksheetAvailable: z.ZodOptional<z.ZodBoolean>;
207
+ worksheetDownloaded: z.ZodOptional<z.ZodBoolean>;
208
+ isComplete: z.ZodBoolean;
209
+ }, z.core.$strip>>;
210
+ updatedAt: z.ZodString;
211
+ createdAt: z.ZodString;
212
+ }, z.core.$strip>;
213
+ type PupilLessonProgress = z.infer<typeof pupilLessonProgressSchema>;
214
+ declare const upsertPupilLessonProgressArgsSchema: z.ZodObject<{
215
+ submissionId: z.ZodString;
216
+ attachmentId: z.ZodString;
217
+ courseId: z.ZodString;
218
+ itemId: z.ZodString;
219
+ pupilLoginHint: z.ZodString;
220
+ starterQuiz: z.ZodOptional<z.ZodObject<{
221
+ grade: z.ZodNumber;
222
+ numQuestions: z.ZodNumber;
223
+ isComplete: z.ZodBoolean;
224
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
225
+ mode: z.ZodEnum<{
226
+ init: "init";
227
+ incomplete: "incomplete";
228
+ input: "input";
229
+ grading: "grading";
230
+ feedback: "feedback";
231
+ }>;
232
+ grade: z.ZodNumber;
233
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
234
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
235
+ correct: "correct";
236
+ incorrect: "incorrect";
237
+ }>, z.ZodArray<z.ZodEnum<{
238
+ correct: "correct";
239
+ incorrect: "incorrect";
240
+ }>>]>>;
241
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
242
+ }, z.core.$strip>>>;
243
+ }, z.core.$strip>>;
244
+ exitQuiz: z.ZodOptional<z.ZodObject<{
245
+ grade: z.ZodNumber;
246
+ numQuestions: z.ZodNumber;
247
+ isComplete: z.ZodBoolean;
248
+ questionResults: z.ZodOptional<z.ZodArray<z.ZodObject<{
249
+ mode: z.ZodEnum<{
250
+ init: "init";
251
+ incomplete: "incomplete";
252
+ input: "input";
253
+ grading: "grading";
254
+ feedback: "feedback";
255
+ }>;
256
+ grade: z.ZodNumber;
257
+ pupilAnswer: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodNull]>>>;
258
+ feedback: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
259
+ correct: "correct";
260
+ incorrect: "incorrect";
261
+ }>, z.ZodArray<z.ZodEnum<{
262
+ correct: "correct";
263
+ incorrect: "incorrect";
264
+ }>>]>>;
265
+ isPartiallyCorrect: z.ZodOptional<z.ZodBoolean>;
266
+ }, z.core.$strip>>>;
267
+ }, z.core.$strip>>;
268
+ video: z.ZodOptional<z.ZodObject<{
269
+ played: z.ZodBoolean;
270
+ duration: z.ZodNumber;
271
+ timeElapsed: z.ZodNumber;
272
+ isComplete: z.ZodBoolean;
273
+ }, z.core.$strip>>;
274
+ intro: z.ZodOptional<z.ZodObject<{
275
+ worksheetAvailable: z.ZodOptional<z.ZodBoolean>;
276
+ worksheetDownloaded: z.ZodOptional<z.ZodBoolean>;
277
+ isComplete: z.ZodBoolean;
278
+ }, z.core.$strip>>;
279
+ }, z.core.$strip>;
280
+ type UpsertPupilLessonProgressArgs = z.infer<typeof upsertPupilLessonProgressArgsSchema>;
281
+
282
+ export { CreateAttachmentCallSchema, UPDATABLE_SUBMISSION_STATES, classroomAttachmentEntitySchema, classroomAttachmentSchema, codeSchema, createAnnouncementAttachmentArgsSchema, googleOAuthUserSchema, introProgressSchema, pupilLessonProgressSchema, questionResultSchema, quizProgressSchema, tokenPayloadSchema, upsertPupilLessonProgressArgsSchema, userCredentialsEntitySchema, videoProgressSchema };
283
+ export type { ClassroomAttachment, ClassroomAttachmentEntity, Code, CreateAnnouncementAttachmentArgs, CreateAttachmentCall, GoogleOAuthUser, PupilLessonProgress, TokenPayload, UpdatableSubmissionState, UpsertPupilLessonProgressArgs, UserCredentialsEntity };
package/dist/views.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import * as zustand from 'zustand';
2
3
 
3
4
  /**
4
5
  * Types related to the UI layer of the application (components/store/views)
@@ -123,8 +124,9 @@ declare const GoogleClassroomAuthSuccessView: React.FC<Props$9>;
123
124
  type Props$8 = {
124
125
  years: Year[];
125
126
  subjectsUrlTemplate: string;
127
+ onYearSelected?: (year: Year) => void;
126
128
  };
127
- declare const GoogleClassroomBrowseView: ({ years, subjectsUrlTemplate, }: Props$8) => React.JSX.Element;
129
+ declare const GoogleClassroomBrowseView: ({ years, subjectsUrlTemplate, onYearSelected, }: Props$8) => React.JSX.Element;
128
130
 
129
131
  type Props$7 = {
130
132
  children: React.ReactNode;
@@ -133,6 +135,7 @@ type Props$7 = {
133
135
  session?: string;
134
136
  accessToken?: string;
135
137
  userProfilePicUrl?: string;
138
+ loginHint?: string;
136
139
  }>;
137
140
  signInUrl: string;
138
141
  cookieKeys?: [
@@ -143,11 +146,20 @@ type Props$7 = {
143
146
  };
144
147
  declare const WithGoogleClassroomAuth: React.FC<Props$7>;
145
148
 
149
+ type OnLessonAttachedData = {
150
+ lessonName: string;
151
+ unitName: string;
152
+ courseId: string;
153
+ itemId: string;
154
+ gradeSyncEnabled: boolean;
155
+ googleLoginHint?: string;
156
+ };
146
157
  type Props$6 = {
147
158
  children: React.ReactNode;
148
159
  createAttachmentAction: (attachment: NewAttachment) => Promise<void>;
160
+ onLessonAttached?: (data: OnLessonAttachedData) => void;
149
161
  };
150
- declare const BrowseLayout: ({ children, createAttachmentAction }: Props$6) => React.JSX.Element;
162
+ declare const BrowseLayout: ({ children, createAttachmentAction, onLessonAttached, }: Props$6) => React.JSX.Element;
151
163
 
152
164
  type Props$5 = {
153
165
  browseData?: LessonListItem[];
@@ -157,8 +169,10 @@ type Props$5 = {
157
169
  headerLeftSlot?: React.ReactElement;
158
170
  programmeUrlTemplate: string;
159
171
  pupilLessonUrlTemplate: string;
172
+ onLessonSelected?: (lessonSlug: string) => void;
173
+ onLessonPreviewed?: (lessonSlug: string) => void;
160
174
  };
161
- declare const LessonListingView: ({ browseData, programmeSlug, unitData, programmeFields, headerLeftSlot, programmeUrlTemplate, pupilLessonUrlTemplate, }: Props$5) => React.JSX.Element;
175
+ declare const LessonListingView: ({ browseData, programmeSlug, unitData, programmeFields, headerLeftSlot, programmeUrlTemplate, pupilLessonUrlTemplate, onLessonSelected, onLessonPreviewed, }: Props$5) => React.JSX.Element;
162
176
 
163
177
  type Props$4<programme = Programme> = {
164
178
  yearSlug?: string;
@@ -170,15 +184,17 @@ type Props$4<programme = Programme> = {
170
184
  factorPrefix: "tier" | "examboard" | "pathway";
171
185
  programmes: programme[];
172
186
  }) => Promise<FactorData[]>;
187
+ onOptionSelected?: (factorType: "tier" | "examboard" | "pathway", factor: FactorData) => void;
173
188
  };
174
- declare const OptionsView: ({ yearSlug, programmes, baseSlug, programmeUrlTemplate, backUrlTemplate, getAvailableProgrammeFactorAction, }: Props$4<never>) => React.JSX.Element;
189
+ declare const OptionsView: ({ yearSlug, programmes, baseSlug, programmeUrlTemplate, backUrlTemplate, getAvailableProgrammeFactorAction, onOptionSelected, }: Props$4<never>) => React.JSX.Element;
175
190
 
176
191
  type Props$3 = {
177
192
  subjects: Subject[];
178
193
  optionsUrlTemplate: string;
179
194
  unitsUrlTemplate: string;
195
+ onSubjectSelected?: (subject: Subject) => void;
180
196
  };
181
- declare const SubjectsPageView: ({ subjects, optionsUrlTemplate, unitsUrlTemplate, }: Props$3) => React.JSX.Element;
197
+ declare const SubjectsPageView: ({ subjects, optionsUrlTemplate, unitsUrlTemplate, onSubjectSelected, }: Props$3) => React.JSX.Element;
182
198
 
183
199
  type Props$2 = {
184
200
  yearSlug: string;
@@ -202,8 +218,48 @@ type Props = {
202
218
  units: Unit[][];
203
219
  programmeSlug: string;
204
220
  unitsLessonListUrlTemplate: string;
221
+ onUnitSelected?: (unit: Unit) => void;
222
+ };
223
+ declare const UnitCards: ({ units, programmeSlug, unitsLessonListUrlTemplate, onUnitSelected, }: Props) => React.JSX.Element;
224
+
225
+ /**
226
+ * Determines if the browser is in Google Classroom
227
+ * based on URL search parameters.
228
+ */
229
+ declare function isClassroomAssignment(searchParams: URLSearchParams | null): boolean;
230
+
231
+ type Lesson = {
232
+ unitSlug: string;
233
+ lessonSlug: string;
234
+ programmeSlug: string;
235
+ title: string;
236
+ unitTitle: string;
237
+ maxPoints: number;
238
+ };
239
+ type UserSlice = {
240
+ userProfilePicUrl?: string;
241
+ googleLoginHint?: string;
242
+ setUser: (profilePicUrl?: string) => void;
243
+ setGoogleLoginHint: (loginHint: string) => void;
244
+ };
245
+ type BrowseSlice = {
246
+ lessons: Lesson[];
247
+ setLessons: (lessons: Lesson[]) => void;
248
+ unsetLessons: () => void;
249
+ lessonSelected: boolean;
250
+ setLessonSelected: () => void;
251
+ isGradeSynced?: boolean;
252
+ toggleGradeSync: (isSynced: boolean) => void;
253
+ };
254
+ type AddonSlice = {
255
+ courseId?: string;
256
+ itemId?: string;
257
+ addOnToken?: string;
258
+ isInitialised: boolean;
259
+ initialiseAddon: (courseId: string, itemId: string, addOnToken: string) => void;
205
260
  };
206
- declare const UnitCards: ({ units, programmeSlug, unitsLessonListUrlTemplate, }: Props) => React.JSX.Element;
261
+ type GoogleClassroomAddonStore = UserSlice & BrowseSlice & AddonSlice;
262
+ declare const useGoogleClassroomAddonStore: zustand.UseBoundStore<zustand.StoreApi<GoogleClassroomAddonStore>>;
207
263
 
208
- export { AuthCookieKeys, BrowseLayout, GoogleClassroomAuthSuccessView, GoogleClassroomBrowseView, GoogleSignInView, LessonListingView, OakGoogleClassroomProvider, OptionsView, SubjectsPageView, UnitCards, UnitsListingView, WithGoogleClassroomAuth };
209
- export type { FactorData, LessonListItem, NewAttachment, Programme, ProgrammeFields, Subject, Unit, UnitData, Year };
264
+ export { AuthCookieKeys, BrowseLayout, GoogleClassroomAuthSuccessView, GoogleClassroomBrowseView, GoogleSignInView, LessonListingView, OakGoogleClassroomProvider, OptionsView, SubjectsPageView, UnitCards, UnitsListingView, WithGoogleClassroomAuth, isClassroomAssignment, useGoogleClassroomAddonStore };
265
+ export type { FactorData, LessonListItem, NewAttachment, OnLessonAttachedData, Programme, ProgrammeFields, Subject, Unit, UnitData, Year };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oaknational/google-classroom-addon",
3
- "version": "1.22.0",
3
+ "version": "1.24.0",
4
4
  "description": "Components and helpers for the Oak Google Classroom Add-on",
5
5
  "exports": {
6
6
  "./ui": {