Skip to content

Commit

Permalink
checkpoint: 01-08-2023 17:40:04
Browse files Browse the repository at this point in the history
  • Loading branch information
purfectliterature committed Aug 1, 2023
1 parent 9e0489e commit 3aca1c3
Show file tree
Hide file tree
Showing 334 changed files with 8,129 additions and 2,970 deletions.
378 changes: 186 additions & 192 deletions .circleci/config.yml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
vendor/**/*
node_modules/**/*
build/**/*
coverage/**
2 changes: 1 addition & 1 deletion client/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ module.exports = {
ignorePropertyModificationsFor: ['draft', 'reducerObject'],
},
],
'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
},
globals: {
window: true,
Expand Down Expand Up @@ -193,7 +194,6 @@ module.exports = {
rules: {
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
'no-unused-vars': 'off',
'no-console': ['error', { allow: ['warn', 'error'] }],
'react-hooks/rules-of-hooks': 'warn',
'react/react-in-jsx-scope': 'off',
'no-param-reassign': 'off',
Expand Down
6 changes: 2 additions & 4 deletions client/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { createBrowserRouter, RouterProvider } from 'react-router-dom';

import Providers from 'lib/components/wrappers/Providers';

import router from './router';
import AuthenticatableApp from './routers/AuthenticatableApp';
import { store } from './store';

const App = (): JSX.Element => (
<Providers store={store}>
<RouterProvider router={createBrowserRouter(router)} />
<AuthenticatableApp />
</Providers>
);

Expand Down
3 changes: 0 additions & 3 deletions client/app/__test__/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ global.$ = jQuery;
global.jQuery = jQuery;
global.buildContextOptions = buildContextOptions;

// Global mocks
document.head.innerHTML = `<meta name="server-context" data-i18n-locale="en" data-time-zone="${timeZone}">`;

window.history.pushState({}, '', `/courses/${courseId}`);

// Global helper functions
Expand Down
15 changes: 0 additions & 15 deletions client/app/api/Attachments.js

This file was deleted.

23 changes: 23 additions & 0 deletions client/app/api/Attachments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import BaseAPI from './Base';
import { APIResponse } from './types';

class AttachmentsAPI extends BaseAPI {
#urlPrefix = '/attachments';

delete(attachmentId: number): APIResponse<unknown> {
return this.client.delete(`${this.#urlPrefix}/${attachmentId}`);
}

upload(file: File): APIResponse<{ success: boolean; id?: number }> {
const formData = new FormData();

formData.append('file', file);
formData.append('name', file.name);

return this.client.post(this.#urlPrefix, formData);
}
}

const attachmentsAPI = new AttachmentsAPI();

export default attachmentsAPI;
88 changes: 85 additions & 3 deletions client/app/api/Users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EmailData,
EmailPostData,
EmailsData,
InvitedSignUpData,
PasswordPostData,
ProfileData,
ProfilePostData,
Expand Down Expand Up @@ -72,13 +73,94 @@ export default class UsersAPI extends BaseAPI {
return this.client.post(url);
}

resendConfirmationEmail(
resendConfirmationEmailByURL(
url: NonNullable<EmailData['confirmationEmailPath']>,
): APIResponse {
return this.client.post(url);
}

signOut(url: string): APIResponse {
return this.client.delete(url);
masquerade(url: string): APIResponse {
return this.client.get(url);
}

stopMasquerade(url: string): APIResponse {
return this.client.get(url);
}

signOut(): APIResponse {
return this.client.delete(`${this.#urlPrefix}/sign_out`);
}

signIn(email: string, password: string, rememberMe: boolean): APIResponse {
const formData = new FormData();

formData.append('user[email]', email);
formData.append('user[password]', password);
formData.append('user[remember_me]', rememberMe ? '1' : '0');

return this.client.post(`${this.#urlPrefix}/sign_in`, formData);
}

signUp(
name: string,
email: string,
password: string,
captchaResponse: string,
invitation?: string,
): APIResponse<{ id: number | null; confirmed: boolean }> {
const formData = new FormData();

formData.append('user[name]', name);
formData.append('user[email]', email);
formData.append('user[password]', password);
formData.append('user[password_confirmation]', password);
formData.append('g-recaptcha-response', captchaResponse);
if (invitation) formData.append('invitation', invitation);

return this.client.post(this.#urlPrefix, formData);
}

verifyInvitationToken(token: string): APIResponse<InvitedSignUpData | null> {
return this.client.get(`${this.#urlPrefix}/sign_up`, {
params: { invitation: token },
});
}

requestResetPassword(email: string): APIResponse {
const formData = new FormData();

formData.append('user[email]', email);

return this.client.post(`${this.#urlPrefix}/password`, formData);
}

resendConfirmationEmail(email: string): APIResponse {
const formData = new FormData();

formData.append('user[email]', email);

return this.client.post(`${this.#urlPrefix}/confirmation`, formData);
}

verifyResetPasswordToken(token: string): APIResponse<{ email: string }> {
return this.client.get(`${this.#urlPrefix}/password/edit`, {
params: { reset_password_token: token },
});
}

resetPassword(token: string, password: string): APIResponse {
const formData = new FormData();

formData.append('user[reset_password_token]', token);
formData.append('user[password]', password);
formData.append('user[password_confirmation]', password);

return this.client.patch(`${this.#urlPrefix}/password`, formData);
}

confirmEmail(token: string): APIResponse<{ email: string }> {
return this.client.get(`${this.#urlPrefix}/confirmation`, {
params: { confirmation_token: token },
});
}
}
62 changes: 21 additions & 41 deletions client/app/api/course/Achievements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
AchievementPermissions,
} from 'types/course/achievements';

import { APIResponse } from 'api/types';

import BaseCourseAPI from './Base';

export default class AchievementsAPI extends BaseCourseAPI {
Expand All @@ -16,40 +18,27 @@ export default class AchievementsAPI extends BaseCourseAPI {
/**
* Fetches a list of achievements in a course.
*/
index(): Promise<
AxiosResponse<{
achievements: AchievementListData[];
permissions: AchievementPermissions;
}>
> {
index(): APIResponse<{
achievements: AchievementListData[];
permissions: AchievementPermissions;
}> {
return this.client.get(this.#urlPrefix);
}

/**
* Fetches an achievement.
*/
fetch(achievementId: number): Promise<
AxiosResponse<{
achievement: AchievementData;
}>
> {
return this.client.get(`${this.#urlPrefix}/${achievementId}`);
fetch(id: number): APIResponse<{ achievement: AchievementData }> {
return this.client.get(`${this.#urlPrefix}/${id}`);
}

/**
* Fetches course users related to an achievement.
*
* @param {number} achievementId
* @return {Promise}
*/
fetchAchievementCourseUsers(achievementId: number): Promise<
AxiosResponse<{
achievementCourseUsers: AchievementCourseUserData[];
}>
> {
return this.client.get(
`${this.#urlPrefix}/${achievementId}/achievement_course_users`,
);
fetchAchievementCourseUsers(id: number): APIResponse<{
achievementCourseUsers: AchievementCourseUserData[];
}> {
return this.client.get(`${this.#urlPrefix}/${id}/achievement_course_users`);
}

/**
Expand All @@ -59,43 +48,34 @@ export default class AchievementsAPI extends BaseCourseAPI {
* {
* achievement: { :title, :description, etc }
* }
* @return {Promise}
* success response: { :id } - ID of created achievement.
* error response: { errors: [] } - An array of errors will be returned upon validation error.
*/
create(params: FormData): Promise<
AxiosResponse<{
id: number;
}>
> {
create(params: FormData): APIResponse<{ id: number }> {
return this.client.post(this.#urlPrefix, params);
}

/**
* Updates the achievement.
*
* @param {number} achievementId
* @param {number} id
* @param {object} params - params in the format of { achievement: { :title, :description, etc } }
* @return {Promise}
* success response: {}
* error response: { errors: [] } - An array of errors will be returned upon validation error.
*/
update(
achievementId: number,
id: number,
params: FormData | object,
): Promise<AxiosResponse> {
return this.client.patch(`${this.#urlPrefix}/${achievementId}`, params);
): APIResponse<{ achievement: AchievementData }> {
return this.client.patch(`${this.#urlPrefix}/${id}`, params);
}

/**
* Deletes an achievement.
*
* @param {number} achievementId
* @return {Promise}
* success response: {}
* error response: {}
*/
delete(achievementId: number): Promise<AxiosResponse> {
return this.client.delete(`${this.#urlPrefix}/${achievementId}`);
}

reorder(ordering: string): APIResponse {
return this.client.post(`${this.#urlPrefix}/reorder`, ordering);
}
}
6 changes: 2 additions & 4 deletions client/app/api/course/Assessment/Assessments.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,10 @@ export default class AssessmentsAPI extends BaseCourseAPI {
}

/**
* Create an assessment attempt.
* Creates an assessment attempt.
*
* @param {number} assessmentId
* @return {Promise}
* success response: { redirectUrl: string }
* error response: { error: string }
* @returns {import('api/types').APIResponse<import('api/types').JustRedirect>}
*/
attempt(assessmentId) {
return this.client.get(`${this.#urlPrefix}/${assessmentId}/attempt`);
Expand Down
23 changes: 18 additions & 5 deletions client/app/api/course/Video/Submissions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AxiosResponse } from 'axios';
import {
VideoEditSubmissionData,
VideoSubmission,
VideoSubmissionAttemptData,
VideoSubmissionData,
} from 'types/course/video/submissions';

import { APIResponse } from 'api/types';

import BaseVideoAPI from './Base';

export default class SubmissionsAPI extends BaseVideoAPI {
Expand All @@ -16,28 +18,39 @@ export default class SubmissionsAPI extends BaseVideoAPI {
/**
* Fetches a list of video submissions for a video in a course.
*/
index(): Promise<AxiosResponse<VideoSubmission>> {
index(): APIResponse<VideoSubmission> {
return this.client.get(this.#getUrlPrefix());
}

/**
* Fetch video submission in a course.
*/
fetch(submissionId): Promise<AxiosResponse<VideoSubmissionData>> {
fetch(submissionId: number): APIResponse<VideoSubmissionData> {
return this.client.get(`${this.#getUrlPrefix()}/${submissionId}`);
}

/**
* Create a video submission in a course.
*/
create(videoId: number): Promise<AxiosResponse<{ submissionId: number }>> {
create(videoId: number): APIResponse<VideoSubmissionAttemptData> {
return this.client.post(`${this.#getUrlPrefix(videoId)}`);
}

/**
* Fetch edit video submission in a course.
*/
edit(submissionId): Promise<AxiosResponse<VideoEditSubmissionData>> {
edit(submissionId: number): APIResponse<VideoEditSubmissionData> {
return this.client.get(`${this.#getUrlPrefix()}/${submissionId}/edit`);
}

/**
* Programmatically attempts to watch a video and get the submission URL.
* Created as a compatibility method for `NextVideoButton`.
*
* @param url URL in the form of `courses/:id/videos/:id/attempt`
* @returns
*/
attempt(url: string): APIResponse<VideoSubmissionAttemptData> {
return this.client.get(url);
}
}
Loading

0 comments on commit 3aca1c3

Please sign in to comment.