Skip to content

Commit

Permalink
fix: portal frontend#8 (#46)
Browse files Browse the repository at this point in the history
* add visibility icon

* fix: text field theme

* fix checkbox field

* fix: repeat field

* auto complete field

* set return type

* date picker field

* re-export date picker field

* fix section

* fix notification

* fix remaining page components

* allow auto complete

* quick save

* generate paths

* add git lens

* custom useParams and useSearchParams

* fix exports

* merge from main

* read only endpoints for all user objects

* fix subpath generation

* fix tests

* add multiple sub paths

* fix path generation

* use location hook

* fix use location hook

* null

* merge from main

* link icon button
  • Loading branch information
SKairinos authored Jul 12, 2024
1 parent 13d99de commit 5c4806e
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 122 deletions.
148 changes: 124 additions & 24 deletions src/api/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,134 @@
import type {
EndpointBuilder,
MutationDefinition,
} from "@reduxjs/toolkit/query"
import { type EndpointBuilder as _EndpointBuilder } from "@reduxjs/toolkit/query/react"

import { type FetchBaseQuery } from "./baseQuery"
import {
buildUrl,
tagData,
type ListArg,
type ListResult,
type RetrieveArg,
type RetrieveResult,
} from "../utils/api"
import type { AuthFactor, Class, School, User } from "./models"
import { type TagTypes } from "./tagTypes"
import urls from "./urls"

export type LogoutQuery = null
export type LogoutResult = null

export default function endpoints<ReducerPath extends string>(
build: EndpointBuilder<FetchBaseQuery, any, ReducerPath>,
): {
logout: MutationDefinition<
LogoutQuery,
FetchBaseQuery,
TagTypes,
LogoutResult,
ReducerPath
>
} {
const _build = build as EndpointBuilder<FetchBaseQuery, TagTypes, ReducerPath>
type EndpointBuilder = _EndpointBuilder<any, any, any>

export function getReadUserEndpoints(build: EndpointBuilder) {
const tagType: TagTypes = "User"

return {
retrieveUser: build.query<
RetrieveResult<
User,
| "first_name"
| "last_name"
| "email"
| "is_active"
| "date_joined"
| "requesting_to_join_class"
| "student"
| "teacher"
>,
RetrieveArg<User>
>({
query: id => ({
url: buildUrl(urls.user.detail, { url: { id } }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
listUsers: build.query<
ListResult<
User,
| "first_name"
| "last_name"
| "email"
| "is_active"
| "date_joined"
| "requesting_to_join_class"
| "student"
| "teacher"
>,
ListArg<{ students_in_class: string }>
>({
query: search => ({
url: buildUrl(urls.user.list, { search }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
}
}

export function getReadSchoolEndpoints(build: EndpointBuilder) {
const tagType: TagTypes = "School"

return {
retrieveSchool: build.query<
RetrieveResult<School, "name" | "country" | "uk_county">,
RetrieveArg<School>
>({
query: id => ({
url: buildUrl(urls.school.detail, { url: { id } }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
}
}

export function getReadClassEndpoints(build: EndpointBuilder) {
const tagType: TagTypes = "Class"

return {
retrieveClass: build.query<
RetrieveResult<
Class,
| "name"
| "read_classmates_data"
| "receive_requests_until"
| "school"
| "teacher"
>,
RetrieveArg<Class>
>({
query: id => ({
url: buildUrl(urls.class.detail, { url: { id } }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
listClasses: build.query<
ListResult<
Class,
| "name"
| "read_classmates_data"
| "receive_requests_until"
| "school"
| "teacher"
>,
ListArg
>({
query: search => ({
url: buildUrl(urls.class.list, { search }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
}
}

export function getReadAuthFactorEndpoints(build: EndpointBuilder) {
const tagType: TagTypes = "AuthFactor"

return {
// TODO: https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#implementing-a-queryfn
logout: _build.mutation<LogoutResult, LogoutQuery>({
query: () => ({
url: "session/logout/",
listAuthFactors: build.query<ListResult<AuthFactor, "type">, ListArg>({
query: search => ({
url: buildUrl(urls.authFactor.list, { search }),
method: "GET",
}),
providesTags: tagData(tagType),
}),
}
}
12 changes: 10 additions & 2 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import baseQuery from "./baseQuery"
import endpoints from "./endpoints"
import {
getReadAuthFactorEndpoints,
getReadClassEndpoints,
getReadSchoolEndpoints,
getReadUserEndpoints,
} from "./endpoints"
import type {
AuthFactor,
Class,
Expand All @@ -14,7 +19,10 @@ import urls from "./urls"

export {
baseQuery,
endpoints,
getReadAuthFactorEndpoints,
getReadClassEndpoints,
getReadSchoolEndpoints,
getReadUserEndpoints,
tagTypes,
urls,
type AuthFactor,
Expand Down
12 changes: 12 additions & 0 deletions src/components/router/LinkIconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IconButton, type IconButtonProps } from "@mui/material"
import type { FC } from "react"
import { Link, type LinkProps } from "react-router-dom"

export type LinkIconButtonProps = Omit<IconButtonProps, "component"> & LinkProps

// https://mui.com/material-ui/integrations/routing/#button
const LinkIconButton: FC<LinkIconButtonProps> = props => {
return <IconButton {...{ ...props, component: Link }} />
}

export default LinkIconButton
3 changes: 3 additions & 0 deletions src/components/router/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import Link, { type LinkProps } from "./Link"
import LinkButton, { type LinkButtonProps } from "./LinkButton"
import LinkIconButton, { type LinkIconButtonProps } from "./LinkIconButton"
import LinkListItem, { type LinkListItemProps } from "./LinkListItem"
import LinkTab, { type LinkTabProps } from "./LinkTab"

export {
Link,
LinkButton,
LinkIconButton,
LinkListItem,
LinkTab,
type LinkButtonProps,
type LinkIconButtonProps,
type LinkListItemProps,
type LinkProps,
type LinkTabProps,
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import {
type UseSessionOptions,
} from "./auth"
import { useCountdown, useEventListener, useExternalScript } from "./general"
import { useNavigate, useParams, useSearchParams } from "./router"
import { useLocation, useNavigate, useParams, useSearchParams } from "./router"

export {
useCountdown,
useEventListener,
useExternalScript,
useLocation,
useNavigate,
useParams,
useSearchParams,
Expand Down
6 changes: 6 additions & 0 deletions src/hooks/router.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {
useLocation as _useLocation,
useNavigate as _useNavigate,
useParams as _useParams,
useSearchParams as _useSearchParams,
type Location,
type NavigateOptions,
type To as NavigateTo,
type Params,
Expand Down Expand Up @@ -37,6 +39,10 @@ export function useNavigate(): <
}
}

export function useLocation<State = {}>() {
return _useLocation() as Location<null | Partial<PageState & State>>
}

// -----------------------------------------------------------------------------
// Use Search Params
// -----------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 5c4806e

Please sign in to comment.