Skip to content

Commit

Permalink
feat: added display user list
Browse files Browse the repository at this point in the history
  • Loading branch information
Sensaz authored and typeWolffo committed Aug 19, 2024
1 parent 237c75d commit 6f8f777
Show file tree
Hide file tree
Showing 38 changed files with 2,022 additions and 147 deletions.
90 changes: 71 additions & 19 deletions apps/web/app/api/generated-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,19 @@ export interface GetAllCategoriesResponse {
};
}

import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, HeadersDefaults, ResponseType } from "axios";
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
HeadersDefaults,
ResponseType,
} from "axios";
import axios from "axios";

export type QueryParamsType = Record<string | number, any>;

export interface FullRequestParams extends Omit<AxiosRequestConfig, "data" | "params" | "url" | "responseType"> {
export interface FullRequestParams
extends Omit<AxiosRequestConfig, "data" | "params" | "url" | "responseType"> {
/** set parameter to `true` for call `securityWorker` for this request */
secure?: boolean;
/** request path */
Expand All @@ -174,11 +181,15 @@ export interface FullRequestParams extends Omit<AxiosRequestConfig, "data" | "pa
body?: unknown;
}

export type RequestParams = Omit<FullRequestParams, "body" | "method" | "query" | "path">;
export type RequestParams = Omit<
FullRequestParams,
"body" | "method" | "query" | "path"
>;

export interface ApiConfig<SecurityDataType = unknown> extends Omit<AxiosRequestConfig, "data" | "cancelToken"> {
export interface ApiConfig<SecurityDataType = unknown>
extends Omit<AxiosRequestConfig, "data" | "cancelToken"> {
securityWorker?: (
securityData: SecurityDataType | null,
securityData: SecurityDataType | null
) => Promise<AxiosRequestConfig | void> | AxiosRequestConfig | void;
secure?: boolean;
format?: ResponseType;
Expand All @@ -198,8 +209,16 @@ export class HttpClient<SecurityDataType = unknown> {
private secure?: boolean;
private format?: ResponseType;

constructor({ securityWorker, secure, format, ...axiosConfig }: ApiConfig<SecurityDataType> = {}) {
this.instance = axios.create({ ...axiosConfig, baseURL: axiosConfig.baseURL || "" });
constructor({
securityWorker,
secure,
format,
...axiosConfig
}: ApiConfig<SecurityDataType> = {}) {
this.instance = axios.create({
...axiosConfig,
baseURL: axiosConfig.baseURL || "",
});
this.secure = secure;
this.format = format;
this.securityWorker = securityWorker;
Expand All @@ -209,15 +228,22 @@ export class HttpClient<SecurityDataType = unknown> {
this.securityData = data;
};

protected mergeRequestParams(params1: AxiosRequestConfig, params2?: AxiosRequestConfig): AxiosRequestConfig {
protected mergeRequestParams(
params1: AxiosRequestConfig,
params2?: AxiosRequestConfig
): AxiosRequestConfig {
const method = params1.method || (params2 && params2.method);

return {
...this.instance.defaults,
...params1,
...(params2 || {}),
headers: {
...((method && this.instance.defaults.headers[method.toLowerCase() as keyof HeadersDefaults]) || {}),
...((method &&
this.instance.defaults.headers[
method.toLowerCase() as keyof HeadersDefaults
]) ||
{}),
...(params1.headers || {}),
...((params2 && params2.headers) || {}),
},
Expand All @@ -238,11 +264,15 @@ export class HttpClient<SecurityDataType = unknown> {
}
return Object.keys(input || {}).reduce((formData, key) => {
const property = input[key];
const propertyContent: any[] = property instanceof Array ? property : [property];
const propertyContent: any[] =
property instanceof Array ? property : [property];

for (const formItem of propertyContent) {
const isFileType = formItem instanceof Blob || formItem instanceof File;
formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));
formData.append(
key,
isFileType ? formItem : this.stringifyFormItem(formItem)
);
}

return formData;
Expand All @@ -266,19 +296,31 @@ export class HttpClient<SecurityDataType = unknown> {
const requestParams = this.mergeRequestParams(params, secureParams);
const responseFormat = format || this.format || undefined;

if (type === ContentType.FormData && body && body !== null && typeof body === "object") {
if (
type === ContentType.FormData &&
body &&
body !== null &&
typeof body === "object"
) {
body = this.createFormData(body as Record<string, unknown>);
}

if (type === ContentType.Text && body && body !== null && typeof body !== "string") {
if (
type === ContentType.Text &&
body &&
body !== null &&
typeof body !== "string"
) {
body = JSON.stringify(body);
}

return this.instance.request({
...requestParams,
headers: {
...(requestParams.headers || {}),
...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}),
...(type && type !== ContentType.FormData
? { "Content-Type": type }
: {}),
},
params: query,
responseType: responseFormat,
Expand All @@ -295,7 +337,9 @@ export class HttpClient<SecurityDataType = unknown> {
*
* Example usage of Swagger with Typebox
*/
export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {
export class API<
SecurityDataType extends unknown,
> extends HttpClient<SecurityDataType> {
auth = {
/**
* No description
Expand Down Expand Up @@ -383,7 +427,7 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
page?: number;
perPage?: number;
},
params: RequestParams = {},
params: RequestParams = {}
) =>
this.request<GetUsersResponse, any>({
path: `/users`,
Expand Down Expand Up @@ -413,7 +457,11 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
* @name UsersControllerUpdateUser
* @request PATCH:/users/{id}
*/
usersControllerUpdateUser: (id: string, data: UpdateUserBody, params: RequestParams = {}) =>
usersControllerUpdateUser: (
id: string,
data: UpdateUserBody,
params: RequestParams = {}
) =>
this.request<UpdateUserResponse, any>({
path: `/users/${id}`,
method: "PATCH",
Expand Down Expand Up @@ -443,7 +491,11 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
* @name UsersControllerChangePassword
* @request PATCH:/users/{id}/change-password
*/
usersControllerChangePassword: (id: string, data: ChangePasswordBody, params: RequestParams = {}) =>
usersControllerChangePassword: (
id: string,
data: ChangePasswordBody,
params: RequestParams = {}
) =>
this.request<ChangePasswordResponse, any>({
path: `/users/${id}/change-password`,
method: "PATCH",
Expand Down Expand Up @@ -494,7 +546,7 @@ export class API<SecurityDataType extends unknown> extends HttpClient<SecurityDa
perPage?: number;
sort?: string;
},
params: RequestParams = {},
params: RequestParams = {}
) =>
this.request<GetAllCategoriesResponse, any>({
path: `/categories`,
Expand Down
1 change: 1 addition & 0 deletions apps/web/app/api/queries/useCurrentUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export function useCurrentUser() {
export function useCurrentUserSuspense() {
return useSuspenseQuery(currentUserQueryOptions);
}
//TODO:
3 changes: 3 additions & 0 deletions apps/web/app/assets/archive-box.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/web/app/assets/pencil.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions apps/web/app/components/CustomSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useMemo } from "react";
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
SelectGroup,
SelectLabel,
} from "~/components/ui/select";

interface SelectGroupProps {
labelValue?: string;
selectItemList: string[];
}

interface CustomSelectProps {
onValueChange?: (value: string) => void;
selectItems: SelectGroupProps[];
value: string;
}

export const CustomSelect: React.FC<CustomSelectProps> = ({
onValueChange,
selectItems,
value,
}) => {
const renderedItems = useMemo(
() =>
selectItems.map(({ labelValue, selectItemList }, groupIndex) => (
<React.Fragment key={groupIndex}>
{labelValue && (
<SelectLabel key={`${groupIndex}${labelValue}`}>
{labelValue}
</SelectLabel>
)}
{selectItemList.map((itemValue, itemIndex) => (
<SelectItem key={itemIndex} value={itemValue}>
{itemValue}
</SelectItem>
))}
</React.Fragment>
)),
[selectItems]
);
return (
<Select value={value} onValueChange={onValueChange}>
<SelectTrigger>
<SelectValue>{value}</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectGroup className="w-auto">{renderedItems}</SelectGroup>
</SelectContent>
</Select>
);
};
85 changes: 85 additions & 0 deletions apps/web/app/components/CustomSelectCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useMemo } from "react";
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
SelectGroup,
SelectLabel,
} from "~/components/ui/select";
import { Checkbox } from "~/components/ui/checkbox";

interface SelectGroupProps {
labelValue?: string;
selectItemList: string[];
}

interface CustomSelectCheckboxProps {
onValueChange?: (value: string[]) => void;
selectItems: SelectGroupProps[];
value: string[];
}

const handleCheckboxChange = (
itemValue: string,
onValueChange: ((value: string[]) => void) | undefined,
value: string[]
) => {
let newValue;
if (value.includes(itemValue)) {
newValue = value.filter((v) => v !== itemValue);
} else {
newValue = [...value, itemValue];
}
if (onValueChange) {
onValueChange(newValue);
}
};

export const CustomSelectCheckbox: React.FC<CustomSelectCheckboxProps> = ({
onValueChange,
selectItems,
value,
}) => {
const renderedItems = useMemo(
() =>
selectItems.map(({ labelValue, selectItemList }, groupIndex) => (
<React.Fragment key={groupIndex}>
{labelValue && (
<SelectLabel key={`${groupIndex}${labelValue}`}>
{labelValue}
</SelectLabel>
)}
{selectItemList.map((itemValue, itemIndex) => (
<SelectItem key={itemIndex} value={itemValue}>
<Checkbox
checked={value.includes(itemValue)}
onCheckedChange={() =>
handleCheckboxChange(itemValue, onValueChange, value)
}
id={`checkbox-${groupIndex}-${itemIndex}`}
/>
<label htmlFor={`checkbox-${groupIndex}-${itemIndex}`}>
{itemValue}
</label>
</SelectItem>
))}
</React.Fragment>
)),
[selectItems, value, onValueChange]
);

return (
<Select value={value.join(", ")} onValueChange={() => {}}>
<SelectTrigger>
<SelectValue>
{value.length > 0 ? value.join(", ") : "Select..."}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectGroup className="w-auto">{renderedItems}</SelectGroup>
</SelectContent>
</Select>
);
};
Loading

0 comments on commit 6f8f777

Please sign in to comment.