Skip to content

Commit

Permalink
quick save
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Aug 9, 2024
1 parent 9baa324 commit 930e1d5
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/pages/studentAccount/StudentAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as page from "codeforlife/components/page"
import { type SessionMetadata, useQueryManager } from "codeforlife/hooks"
import { type FC } from "react"
import { LinkButton } from "codeforlife/components/router"
import { Typography } from "@mui/material"

import UpdateAccountForm from "./UpdateAccountForm"
import { paths } from "../../router"
import { useRetrieveUserQuery } from "../../api/user"

export interface StudentAccountProps {
userType: "student" | "indy"
}

const _StudentAccount: FC<SessionMetadata> = ({ user_type, user_id }) =>
useQueryManager(useRetrieveUserQuery, user_id, user => (
<>
<page.Banner

Check failure on line 18 in src/pages/studentAccount/StudentAccount.tsx

View workflow job for this annotation

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

Property 'subheader' is missing in type '{ header: string; textAlign: "center"; bgcolor: "secondary" | "tertiary"; }' but required in type 'BannerProps'.
header={`Welcome, ${user.first_name}`}
textAlign="center"
bgcolor={user_type === "student" ? "tertiary" : "secondary"}
/>
<page.Section>
<UpdateAccountForm user={user} />
</page.Section>
{user_type === "indy" && (
<>
<page.Section boxProps={{ bgcolor: "info.main" }}>
<Typography variant="h5">Join a school or club</Typography>
<Typography>
To find out about linking your Code For Life account with a school
or club, click &apos;Join&apos;.
</Typography>
<LinkButton to={paths.indy.dashboard.joinClass._}>Join</LinkButton>
</page.Section>
<page.Section>
{/* <DeleteAccountForm userType="independent" /> */}
</page.Section>
</>
)}
</>
))

const StudentAccount: FC<StudentAccountProps> = ({ userType }) => (
<page.Page session={{ userType }}>{_StudentAccount}</page.Page>
)

export default StudentAccount
155 changes: 155 additions & 0 deletions src/pages/studentAccount/UpdateAccountForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import * as forms from "codeforlife/components/form"
import { Stack, Typography } from "@mui/material"
import { type FC } from "react"
import { LinkButton } from "codeforlife/components/router"
import { submitForm } from "codeforlife/utils/form"
import { useNavigate } from "codeforlife/hooks"

import {
type RetrieveUserResult,
type UpdateUserArg,
useUpdateUserMutation,
} from "../../api/user"
import { LastNameField } from "../../components/form"

export interface UpdateAccountFormProps {
user: RetrieveUserResult
}

const UpdateAccountForm: FC<UpdateAccountFormProps> = ({ user }) => {
const [updateUser] = useUpdateUserMutation()
const navigate = useNavigate()

const initialValues = user.student
? {
id: user.id,
password: "",
password_repeat: "",
current_password: "",
}
: {
id: user.id,
password: "",
password_repeat: "",
current_password: "",
first_name: user.first_name,
last_name: user.last_name,
email: user.email,
}

return (
<>
{user.student ? (
<>
<Typography align="center" variant="h4">
Update your password
</Typography>
<Typography>
You may edit your password below. It must be long enough and hard
enough to stop your friends guessing it and stealing all of your
hard work. Choose something memorable though.
</Typography>
<Typography>
If you have any problems, ask a teacher to help you.
</Typography>
</>
) : (
<>
<Typography align="center" variant="h4">
Update your account details
</Typography>
<Typography>You can update your account details below.</Typography>
<Typography>
Please note: If you change your email address, you will need to
re-verify it. Please ensure your password is strong enough to be
secure.
</Typography>
</>
)}
<forms.Form
initialValues={initialValues}
onSubmit={submitForm(updateUser, {
onlyDirtyValues: initialValues,
exclude: ["password_repeat"],
clean: values => {

Check failure on line 74 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Parameter 'values' implicitly has an 'any' type.
if (user.student) {
const { id, password, current_password } =
values as typeof initialStudentValues

Check failure on line 77 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Cannot find name 'initialStudentValues'.

return { id, password, current_password }
}

const { id, first_name, last_name } =
values as typeof initialIndyValues

Check failure on line 83 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Cannot find name 'initialIndyValues'. Did you mean 'initialValues'?

return { id, first_name, last_name }
},
then: (_, values) => {

Check failure on line 87 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Type '(_: any, values: any) => void' is not assignable to type '(result: UpdateUserResult) => void'.

Check failure on line 87 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Parameter '_' implicitly has an 'any' type.

Check failure on line 87 in src/pages/studentAccount/UpdateAccountForm.tsx

View workflow job for this annotation

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

Parameter 'values' implicitly has an 'any' type.
const messages = [
"Your account details have been changed successfully.",
]
if (values.email !== initialValues.email) {
// TODO: implement this behavior on the backend.
messages.push(
"Your email will be changed once you have verified it, until then you can still log in with your old email.",
)
}
if (values.password !== initialValues.password) {
messages.push(
"Going forward, please login using your new password.",
)
}

navigate(".", {
state: {
notifications: messages.map(message => ({
props: { children: message },
})),
},
})
},
})}
>
{form => {
// Checking if individual fields are dirty is not currently supported.
// https://github.com/jaredpalmer/formik/issues/1421
const dirty = {
email: form.values.email !== form.initialValues.email,
password: form.values.password !== form.initialValues.password,
}

return (
<>
{!user.student && (
<>
<forms.FirstNameField />
<LastNameField />
<forms.EmailField />
</>
)}
<forms.PasswordField
withRepeatField={Boolean(user.student) || dirty.password}
/>
{(Boolean(user.student) || dirty.email || dirty.password) && (
<forms.PasswordField
required
name="current_password"
label="Current password"
placeholder="Enter your current password"
/>
)}
<Stack direction="row" spacing={2} paddingY={3}>
<LinkButton variant="outlined" to={-1}>
Cancel
</LinkButton>
<forms.SubmitButton>Update details</forms.SubmitButton>
</Stack>
</>
)
}}
</forms.Form>
</>
)
}

export default UpdateAccountForm
9 changes: 9 additions & 0 deletions src/router/routes/student.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { Route } from "react-router-dom"

// import Student from '../../pages/student/Student';
import StudentAccount from "../../pages/studentAccount/StudentAccount"
import StudentDashboard from "../../pages/studentDashboard/StudentDashboard"
import paths from "../paths"

const student = (
<>
{/* <Route path={paths.student._} element={<Student />} /> */}
<Route
path={paths.student.dashboard.account._}
element={<StudentAccount userType="student" />}
/>
<Route
path={paths.indy.dashboard.account._}
element={<StudentAccount userType="indy" />}
/>
<Route
path={paths.student.dashboard._}
element={<StudentDashboard userType="student" />}
Expand Down

0 comments on commit 930e1d5

Please sign in to comment.