@oaknational/google-classroom-addon 1.21.0 → 1.23.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,6 +40,143 @@ 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;
@@ -53,6 +191,9 @@ declare class OakGoogleClassroomAddOn {
53
191
  private oauthService;
54
192
  private sessionService;
55
193
  private classroomAttachmentService;
194
+ private pupilProgressService;
195
+ private encryptionService;
196
+ private firestoreClient;
56
197
  constructor(encryptionSecret: string, firestore: Firestore, googleOAuthClientId: string, googleOAuthClientSecret: string, googleOAuthCallbackApiRoute: string, sessionSecret: string, baseUrl: string);
57
198
  /**
58
199
  * Generates the Google OAuth sign-in URL for user authentication.
@@ -90,6 +231,47 @@ declare class OakGoogleClassroomAddOn {
90
231
  * @param session - The user's encrypted session string
91
232
  */
92
233
  createAttachment(args: CreateAnnouncementAttachmentArgs, accessToken: string, session: string): Promise<ClassroomAttachmentEntity | null>;
234
+ /**
235
+ * Gets the add-on context from Google Classroom for the current pupil.
236
+ * Returns the studentContext including submissionId, plus the pupilLoginHint
237
+ * extracted from the session.
238
+ * @param courseId - The Google Classroom course ID
239
+ * @param itemId - The courseWork item ID
240
+ * @param attachmentId - The attachment ID
241
+ * @param accessToken - The pupil's current OAuth access token
242
+ * @param session - The pupil's encrypted session string
243
+ */
244
+ getAddOnContext(courseId: string, itemId: string, attachmentId: string, accessToken: string, session: string): Promise<{
245
+ pupilLoginHint: string;
246
+ courseId?: string | null;
247
+ itemId?: string | null;
248
+ postId?: string | null;
249
+ studentContext?: _googleapis_classroom.classroom_v1.Schema$StudentContext;
250
+ supportsStudentWork?: boolean | null;
251
+ teacherContext?: _googleapis_classroom.classroom_v1.Schema$TeacherContext;
252
+ }>;
253
+ /**
254
+ * Resolves a teacher OAuth client by looking up the attachment's teacherLoginHint
255
+ * and fetching the teacher's stored credentials from Firestore.
256
+ * In dev mode, falls back to GOOGLE_CLASSROOM_DEV_REFRESH_TOKEN if teacher credentials are not found.
257
+ * @param attachmentId - The attachment ID to look up the teacher for.
258
+ * @returns A GoogleOAuthClient authenticated with teacher credentials, or undefined if unavailable.
259
+ */
260
+ private resolveTeacherOAuthClient;
261
+ /**
262
+ * Upserts pupil lesson progress to Firestore and updates GC pointsEarned
263
+ * when the exit quiz is newly completed, using the teacher's OAuth credentials.
264
+ * @param args - The lesson progress data
265
+ * @param accessToken - The pupil's current OAuth access token
266
+ * @param session - The pupil's encrypted session string
267
+ */
268
+ upsertPupilLessonProgress(args: UpsertPupilLessonProgressArgs, accessToken: string, session: string): Promise<PupilLessonProgress>;
269
+ /**
270
+ * Retrieves pupil lesson progress from Firestore.
271
+ * Does not require Google Classroom authentication.
272
+ * @param submissionId - The Google Classroom submission ID
273
+ */
274
+ getPupilLessonProgress(submissionId: string): Promise<PupilLessonProgress | null>;
93
275
  }
94
276
 
95
277
  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
@@ -7,6 +7,7 @@ type LessonListItem = {
7
7
  programmeSlug: string;
8
8
  unitSlug: string;
9
9
  lessonSlug: string;
10
+ exitQuizCount: number;
10
11
  isLegacy: boolean;
11
12
  lessonData: {
12
13
  keyLearningPoints?: {
@@ -101,7 +102,7 @@ declare enum AuthCookieKeys {
101
102
  PupilSession = "oak-gclassroom-pupil-session"
102
103
  }
103
104
 
104
- type Props$9 = {
105
+ type Props$a = {
105
106
  getGoogleSignInLink: (subscribeToNewsletter?: boolean) => Promise<string | null>;
106
107
  onSuccessfulSignIn: (signUpToNewsletter: boolean) => Promise<void> | void;
107
108
  privacyPolicyUrl: string;
@@ -111,21 +112,21 @@ type Props$9 = {
111
112
  AuthCookieKeys.Session | AuthCookieKeys.PupilSession
112
113
  ];
113
114
  };
114
- declare const GoogleSignInView: ({ getGoogleSignInLink, onSuccessfulSignIn, privacyPolicyUrl, showMailingListOption, cookieKeys, }: Props$9) => React.JSX.Element;
115
+ declare const GoogleSignInView: ({ getGoogleSignInLink, onSuccessfulSignIn, privacyPolicyUrl, showMailingListOption, cookieKeys, }: Props$a) => React.JSX.Element;
115
116
 
116
- type Props$8 = {
117
+ type Props$9 = {
117
118
  session: string;
118
119
  accessToken: string;
119
120
  };
120
- declare const GoogleClassroomAuthSuccessView: React.FC<Props$8>;
121
+ declare const GoogleClassroomAuthSuccessView: React.FC<Props$9>;
121
122
 
122
- type Props$7 = {
123
+ type Props$8 = {
123
124
  years: Year[];
124
125
  subjectsUrlTemplate: string;
125
126
  };
126
- declare const GoogleClassroomBrowseView: ({ years, subjectsUrlTemplate, }: Props$7) => React.JSX.Element;
127
+ declare const GoogleClassroomBrowseView: ({ years, subjectsUrlTemplate, }: Props$8) => React.JSX.Element;
127
128
 
128
- type Props$6 = {
129
+ type Props$7 = {
129
130
  children: React.ReactNode;
130
131
  verifySessionAction: () => Promise<{
131
132
  authenticated: boolean;
@@ -140,15 +141,15 @@ type Props$6 = {
140
141
  ];
141
142
  onVerifySuccess?: () => void | Promise<void>;
142
143
  };
143
- declare const WithGoogleClassroomAuth: React.FC<Props$6>;
144
+ declare const WithGoogleClassroomAuth: React.FC<Props$7>;
144
145
 
145
- type Props$5 = {
146
+ type Props$6 = {
146
147
  children: React.ReactNode;
147
148
  createAttachmentAction: (attachment: NewAttachment) => Promise<void>;
148
149
  };
149
- declare const BrowseLayout: ({ children, createAttachmentAction }: Props$5) => React.JSX.Element;
150
+ declare const BrowseLayout: ({ children, createAttachmentAction }: Props$6) => React.JSX.Element;
150
151
 
151
- type Props$4 = {
152
+ type Props$5 = {
152
153
  browseData?: LessonListItem[];
153
154
  programmeSlug: string;
154
155
  unitData?: UnitData;
@@ -157,9 +158,9 @@ type Props$4 = {
157
158
  programmeUrlTemplate: string;
158
159
  pupilLessonUrlTemplate: string;
159
160
  };
160
- declare const LessonListingView: ({ browseData, programmeSlug, unitData, programmeFields, headerLeftSlot, programmeUrlTemplate, pupilLessonUrlTemplate, }: Props$4) => React.JSX.Element;
161
+ declare const LessonListingView: ({ browseData, programmeSlug, unitData, programmeFields, headerLeftSlot, programmeUrlTemplate, pupilLessonUrlTemplate, }: Props$5) => React.JSX.Element;
161
162
 
162
- type Props$3<programme = Programme> = {
163
+ type Props$4<programme = Programme> = {
163
164
  yearSlug?: string;
164
165
  programmes: Programme[];
165
166
  baseSlug: string;
@@ -170,33 +171,45 @@ type Props$3<programme = Programme> = {
170
171
  programmes: programme[];
171
172
  }) => Promise<FactorData[]>;
172
173
  };
173
- declare const OptionsView: ({ yearSlug, programmes, baseSlug, programmeUrlTemplate, backUrlTemplate, getAvailableProgrammeFactorAction, }: Props$3<never>) => React.JSX.Element;
174
+ declare const OptionsView: ({ yearSlug, programmes, baseSlug, programmeUrlTemplate, backUrlTemplate, getAvailableProgrammeFactorAction, }: Props$4<never>) => React.JSX.Element;
174
175
 
175
- type Props$2 = {
176
+ type Props$3 = {
176
177
  subjects: Subject[];
177
178
  optionsUrlTemplate: string;
178
179
  unitsUrlTemplate: string;
179
180
  };
180
- declare const SubjectsPageView: ({ subjects, optionsUrlTemplate, unitsUrlTemplate, }: Props$2) => React.JSX.Element;
181
+ declare const SubjectsPageView: ({ subjects, optionsUrlTemplate, unitsUrlTemplate, }: Props$3) => React.JSX.Element;
181
182
 
182
- type Props$1 = {
183
- programmeSlug: string;
183
+ type Props$2 = {
184
184
  yearSlug: string;
185
185
  programmeUnits: Unit[][];
186
186
  programmeData: ProgrammeFields;
187
- unitsLessonListUrlTemplate: string;
188
187
  subjectsUrlTemplate: string;
189
188
  headerLeftSlot?: React.ReactElement;
189
+ children?: React.ReactElement;
190
190
  };
191
- declare const UnitsListingView: ({ programmeSlug, programmeUnits, programmeData, yearSlug, unitsLessonListUrlTemplate, subjectsUrlTemplate, headerLeftSlot, }: Props$1) => React.JSX.Element;
191
+ declare const UnitsListingView: ({ programmeUnits, programmeData, yearSlug, subjectsUrlTemplate, headerLeftSlot, children, }: Props$2) => React.JSX.Element;
192
192
 
193
- type Props = {
193
+ type Props$1 = {
194
194
  children: React.ReactNode;
195
195
  courseId: string;
196
196
  itemId: string;
197
197
  addOnToken: string;
198
198
  };
199
- declare const OakGoogleClassroomProvider: ({ children, courseId, itemId, addOnToken, }: Props) => React.ReactNode;
199
+ declare const OakGoogleClassroomProvider: ({ children, courseId, itemId, addOnToken, }: Props$1) => React.ReactNode;
200
+
201
+ type Props = {
202
+ units: Unit[][];
203
+ programmeSlug: string;
204
+ unitsLessonListUrlTemplate: string;
205
+ };
206
+ declare const UnitCards: ({ units, programmeSlug, unitsLessonListUrlTemplate, }: Props) => React.JSX.Element;
207
+
208
+ /**
209
+ * Determines if the browser is in Google Classroom
210
+ * based on URL search parameters.
211
+ */
212
+ declare function isClassroomAssignment(searchParams: URLSearchParams | null): boolean;
200
213
 
201
- export { AuthCookieKeys, BrowseLayout, GoogleClassroomAuthSuccessView, GoogleClassroomBrowseView, GoogleSignInView, LessonListingView, OakGoogleClassroomProvider, OptionsView, SubjectsPageView, UnitsListingView, WithGoogleClassroomAuth };
214
+ export { AuthCookieKeys, BrowseLayout, GoogleClassroomAuthSuccessView, GoogleClassroomBrowseView, GoogleSignInView, LessonListingView, OakGoogleClassroomProvider, OptionsView, SubjectsPageView, UnitCards, UnitsListingView, WithGoogleClassroomAuth, isClassroomAssignment };
202
215
  export type { FactorData, LessonListItem, NewAttachment, 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.21.0",
3
+ "version": "1.23.0",
4
4
  "description": "Components and helpers for the Oak Google Classroom Add-on",
5
5
  "exports": {
6
6
  "./ui": {
@@ -55,13 +55,13 @@
55
55
  "peerDependencies": {
56
56
  "@google-cloud/firestore": ">=7.11.2",
57
57
  "@googleapis/classroom": "4.9.0",
58
- "@oaknational/oak-components": ">=1.173.0",
58
+ "@oaknational/oak-components": "^2.5.0",
59
59
  "google-auth-library": "9.15.1",
60
60
  "next": ">=15.4.3",
61
61
  "react": ">=18.3.1",
62
62
  "react-dom": ">=18.3.1",
63
- "zustand": ">=5.0.9",
64
- "zod": ">=3.25.76"
63
+ "zod": ">=3.25.76",
64
+ "zustand": ">=5.0.9"
65
65
  },
66
66
  "dependencies": {
67
67
  "iron-session": "^8.0.4",