Skip to content

Commit

Permalink
Portal frontend#19 (#22)
Browse files Browse the repository at this point in the history
* export results and args

* new js package

* add icon

* table components

* quick save

* extract id from body

* school name field

* ready for review

* only teachers

* fix rendering issue and create placeholder tabs

* merge from dev

* new js package

* fix reset password form

* feedback

* added todo
  • Loading branch information
SKairinos authored Aug 7, 2024
1 parent 8727016 commit 10b08fe
Show file tree
Hide file tree
Showing 27 changed files with 1,192 additions and 95 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"✅ Do add `devDependencies` below that are `peerDependencies` in the CFL package."
],
"dependencies": {
"codeforlife": "github:ocadotechnology/codeforlife-package-javascript#v2.1.4",
"codeforlife": "github:ocadotechnology/codeforlife-package-javascript#v2.2.0",
"crypto-js": "^4.2.0"
},
"devDependencies": {
Expand Down
38 changes: 28 additions & 10 deletions src/api/klass.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { type Class, urls } from "codeforlife/api"
import getReadClassEndpoints, {
CLASS_TAG,
type ListClassesArg,
type ListClassesResult,
type RetrieveClassArg,
type RetrieveClassResult,
} from "codeforlife/api/endpoints/klass"
import {

Check failure on line 9 in src/api/klass.ts

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Imports should be sorted alphabetically
type BulkUpdateArg,
type BulkUpdateResult,
type CreateArg,
type CreateResult,
type DestroyArg,
Expand All @@ -9,21 +18,14 @@ import {
buildUrl,
tagData,
} from "codeforlife/utils/api"
import getReadClassEndpoints, {
CLASS_TAG,
type ListClassesArg,
type ListClassesResult,
type RetrieveClassArg,
type RetrieveClassResult,
} from "codeforlife/api/endpoints/klass"

import api from "."

export type {
RetrieveClassArg,
RetrieveClassResult,
ListClassesArg,
ListClassesResult,
RetrieveClassArg,
RetrieveClassResult,
}

export type CreateClassResult = CreateResult<Class>
Expand All @@ -43,6 +45,13 @@ export type UpdateClassArg = UpdateArg<
"name" | "read_classmates_data" | "receive_requests_until" | "teacher"
>

export type UpdateClassesResult = BulkUpdateResult<Class>
export type UpdateClassesArg = BulkUpdateArg<
Class,
never,
"name" | "read_classmates_data" | "receive_requests_until" | "teacher"
>

const classApi = api.injectEndpoints({
endpoints: build => ({
...getReadClassEndpoints(build),
Expand All @@ -61,13 +70,21 @@ const classApi = api.injectEndpoints({
invalidatesTags: tagData(CLASS_TAG),
}),
updateClass: build.mutation<UpdateClassResult, UpdateClassArg>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.class.detail, { url: { id } }),
method: "PATCH",
body,
}),
invalidatesTags: tagData(CLASS_TAG),
}),
updateClasses: build.mutation<UpdateClassesResult, UpdateClassesArg>({
query: body => ({
url: urls.class.list + "bulk/",
method: "PATCH",
body,
}),
invalidatesTags: tagData(CLASS_TAG),
}),
}),
})

Expand All @@ -80,4 +97,5 @@ export const {
useLazyRetrieveClassQuery,
useListClassesQuery,
useLazyListClassesQuery,
useUpdateClassesMutation,
} = classApi
14 changes: 7 additions & 7 deletions src/api/school.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { type School, urls } from "codeforlife/api"
import getReadSchoolEndpoints, {
type RetrieveSchoolArg,
type RetrieveSchoolResult,
SCHOOL_TAG,
} from "codeforlife/api/endpoints/school"
import {

Check failure on line 7 in src/api/school.ts

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Imports should be sorted alphabetically
type CreateArg,
type CreateResult,
Expand All @@ -6,12 +12,6 @@ import {
buildUrl,
tagData,
} from "codeforlife/utils/api"
import { type School, urls } from "codeforlife/api"
import getReadSchoolEndpoints, {
type RetrieveSchoolArg,
type RetrieveSchoolResult,
SCHOOL_TAG,
} from "codeforlife/api/endpoints/school"

import api from "."

Expand All @@ -38,7 +38,7 @@ const schoolApi = api.injectEndpoints({
}),
}),
updateSchool: build.mutation<UpdateSchoolResult, UpdateSchoolArg>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.school.detail, { url: { id } }),
method: "PATCH",
body,
Expand Down
18 changes: 8 additions & 10 deletions src/api/schoolTeacherInvitation.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type User } from "codeforlife/api"
import {

Check failure on line 2 in src/api/schoolTeacherInvitation.ts

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Expected 'multiple' syntax before 'single' syntax
type Arg,
type CreateArg,
Expand All @@ -14,7 +15,6 @@ import {
buildUrl,
tagData,
} from "codeforlife/utils/api"
import { type User } from "codeforlife/api"

import api from "."

Expand All @@ -30,14 +30,12 @@ export type SchoolTeacherInvitation = Model<
>

export type AcceptSchoolTeacherInvitationResult = null
export type AcceptSchoolTeacherInvitationArg = [
SchoolTeacherInvitation["id"],
{
user?: Arg<User, "first_name" | "last_name" | "password" | "email"> & {
add_to_newsletter: boolean
}
},
]
export type AcceptSchoolTeacherInvitationArg = {
id: SchoolTeacherInvitation["id"]
user?: Arg<User, "first_name" | "last_name" | "password" | "email"> & {
add_to_newsletter: boolean
}
}

export type RejectSchoolTeacherInvitationResult = null
export type RejectSchoolTeacherInvitationArg = SchoolTeacherInvitation["id"]
Expand Down Expand Up @@ -95,7 +93,7 @@ const schoolTeacherInvitationApi = api.injectEndpoints({
AcceptSchoolTeacherInvitationResult,
AcceptSchoolTeacherInvitationArg
>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(detailUrl + "accept/", { url: { id } }),
method: "DELETE",
body,
Expand Down
10 changes: 7 additions & 3 deletions src/api/teacher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ const teacherApi = api.injectEndpoints({
RemoveTeacherFromSchoolArg
>({
query: id => ({
url: buildUrl(urls.teacher.detail, { url: { id } }),
url: buildUrl(urls.teacher.detail + "remove-from-school/", {
url: { id },
}),
method: "PUT",
}),
invalidatesTags: tagData("User", "user"),
Expand All @@ -51,8 +53,10 @@ const teacherApi = api.injectEndpoints({
SetTeacherAdminAccessResult,
SetTeacherAdminAccessArg
>({
query: ([id, body]) => ({
url: buildUrl(urls.teacher.detail, { url: { id } }),
query: ({ id, ...body }) => ({
url: buildUrl(urls.teacher.detail + "set-admin-access/", {
url: { id },
}),
method: "PUT",
body,
}),
Expand Down
65 changes: 26 additions & 39 deletions src/api/user.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { type User, urls } from "codeforlife/api"
import getReadUserEndpoints, {
type ListUsersArg,
type ListUsersResult,
type RetrieveUserArg,
type RetrieveUserResult,
USER_TAG,
} from "codeforlife/api/endpoints/user"
import {

Check failure on line 9 in src/api/user.ts

View workflow job for this annotation

GitHub Actions / main / test / test-js-code

Imports should be sorted alphabetically
type Arg,
type CreateArg,
Expand All @@ -9,62 +17,41 @@ import {
buildUrl,
tagData,
} from "codeforlife/utils/api"
import { type User, urls } from "codeforlife/api"
import getReadUserEndpoints, {
type ListUsersArg,
type ListUsersResult,
type RetrieveUserArg,
type RetrieveUserResult,
USER_TAG,
} from "codeforlife/api/endpoints/user"

import api from "."

export type {
RetrieveUserArg,
RetrieveUserResult,
ListUsersArg,
ListUsersResult,
RetrieveUserArg,
RetrieveUserResult,
}

export type HandleJoinClassRequestResult = UpdateResult<User>
export type HandleJoinClassRequestArg = UpdateArg<
User,
never,
"first_name",
{ accept: boolean }
>
export type HandleJoinClassRequestArg = UpdateArg<User, never, "first_name"> & {
accept: boolean
}

export type RequestPasswordResetResult = null
export type RequestPasswordResetArg = Arg<User, "email">

export type ResetPasswordResult = UpdateResult<User>
export type ResetPasswordArg = UpdateArg<
User,
"password",
never,
{ token: string }
>
export type ResetPasswordArg = UpdateArg<User, "password", never> & {
token: string
}

export type VerifyEmailAddressResult = UpdateResult<User>
export type VerifyEmailAddressArg = UpdateArg<
User,
never,
never,
{ token: string }
>
export type VerifyEmailAddressArg = {
id: User["id"]
token: string
}

export type UpdateUserResult = UpdateResult<User>
export type UpdateUserArg = UpdateArg<
User,
never,
| "first_name"
| "last_name"
| "email"
| "requesting_to_join_class"
| "password",
{ current_password?: string }
>
"first_name" | "last_name" | "email" | "requesting_to_join_class" | "password"
> & { current_password?: string }

export type DestroyIndependentUserResult = DestroyResult
export type DestroyIndependentUserArg = DestroyArg<User>
Expand All @@ -85,7 +72,7 @@ const userApi = api.injectEndpoints({
HandleJoinClassRequestResult,
HandleJoinClassRequestArg
>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.user.detail + "handle-join-class-request/", {
url: { id },
}),
Expand All @@ -105,7 +92,7 @@ const userApi = api.injectEndpoints({
}),
}),
resetPassword: build.mutation<ResetPasswordResult, ResetPasswordArg>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.user.detail + "reset-password/", { url: { id } }),
method: "PUT",
body,
Expand All @@ -115,7 +102,7 @@ const userApi = api.injectEndpoints({
VerifyEmailAddressResult,
VerifyEmailAddressArg
>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.user.detail + "verify-email-address/", {
url: { id },
}),
Expand All @@ -124,7 +111,7 @@ const userApi = api.injectEndpoints({
}),
}),
updateUser: build.mutation<UpdateUserResult, UpdateUserArg>({
query: ([id, body]) => ({
query: ({ id, ...body }) => ({
url: buildUrl(urls.user.detail, { url: { id } }),
method: "PATCH",
body,
Expand Down
11 changes: 11 additions & 0 deletions src/components/form/LastNameField.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { TextField, type TextFieldProps } from "codeforlife/components/form"
import { type FC } from "react"
import { InputAdornment } from "@mui/material"
import { PersonOutlined as PersonOutlinedIcon } from "@mui/icons-material"
import { string as YupString } from "yup"

export type LastNameFieldProps = Omit<
Expand All @@ -12,13 +14,22 @@ const LastNameField: FC<LastNameFieldProps> = ({
name = "last_name",
label = "Last name",
placeholder = "Enter your last name",
InputProps = {},
...otherTextFieldProps
}) => (
<TextField
schema={YupString().max(150)}
name={name}
label={label}
placeholder={placeholder}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<PersonOutlinedIcon />
</InputAdornment>
),
...InputProps,
}}
{...otherTextFieldProps}
/>
)
Expand Down
28 changes: 28 additions & 0 deletions src/components/form/SchoolNameField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as yup from "yup"
import { Business as BusinessIcon } from "@mui/icons-material"
import { type FC } from "react"
import { InputAdornment } from "@mui/material"
import { TextField } from "codeforlife/components/form"

export interface SchoolNameFieldProps {}

const SchoolNameField: FC<SchoolNameFieldProps> = () => {
return (
<TextField
required
schema={yup.string().max(200)}
name="name"
label="Name of school or club"
placeholder="Enter name of school or club"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<BusinessIcon />
</InputAdornment>
),
}}
/>
)
}

export default SchoolNameField
3 changes: 3 additions & 0 deletions src/components/form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import LastNameField, { type LastNameFieldProps } from "./LastNameField"
import NewPasswordField, {
type NewPasswordFieldProps,
} from "./NewPasswordField"
import SchoolNameField, { type SchoolNameFieldProps } from "./SchoolNameField"

export {
LastNameField,
NewPasswordField,
type LastNameFieldProps,
type NewPasswordFieldProps,
SchoolNameField,
type SchoolNameFieldProps,
}
Loading

0 comments on commit 10b08fe

Please sign in to comment.