diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa03275 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +* Make `Page` component +* TextInput -> Select diff --git a/src/App.tsx b/src/App.tsx index 0483b09..bf9fb78 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,7 @@ import {CssBaseline, ThemeProvider} from "@mui/material" import {queryClient} from "~/constants/react-query" import {lightTheme} from "~/constants/themes" import {getServerSettings} from "~/apis" +import AliasDetailRoute from "~/routes/AliasDetailRoute" import AliasesRoute from "~/routes/AliasesRoute" import AuthContextProvider from "~/AuthContext/AuthContextProvider" import AuthenticateRoute from "~/routes/AuthenticateRoute" @@ -60,6 +61,10 @@ const router = createBrowserRouter([ path: "/aliases", element: , }, + { + path: "/aliases/:addressInBase64", + element: , + }, { path: "/settings", element: , diff --git a/src/apis/create-alias.ts b/src/apis/create-alias.ts index 355b0ef..4ecfc1d 100644 --- a/src/apis/create-alias.ts +++ b/src/apis/create-alias.ts @@ -9,11 +9,12 @@ import {client} from "~/constants/axios-client" interface CreateAliasDataOther { isActive?: boolean encryptedNotes?: string - removeTrackers?: boolean - createMailReport?: boolean - proxyImages?: boolean - imageProxyFormat?: ImageProxyFormatType - imageProxyUserAgent?: ProxyUserAgentType + + prefRemoveTrackers?: boolean + prefCreateMailReport?: boolean + prefProxyImages?: boolean + prefImageProxyFormat?: ImageProxyFormatType + prefImageProxyUserAgent?: ProxyUserAgentType } interface CreateAliasDataBase extends CreateAliasDataOther { diff --git a/src/apis/get-alias.ts b/src/apis/get-alias.ts new file mode 100644 index 0000000..656721a --- /dev/null +++ b/src/apis/get-alias.ts @@ -0,0 +1,13 @@ +import {client} from "~/constants/axios-client" +import {Alias} from "~/server-types" + +export default async function getAlias(address: string): Promise { + const {data} = await client.get( + `${import.meta.env.VITE_SERVER_BASE_URL}/alias/${address}`, + { + withCredentials: true, + }, + ) + + return data +} diff --git a/src/apis/get-aliases.ts b/src/apis/get-aliases.ts index 10ada02..932972a 100644 --- a/src/apis/get-aliases.ts +++ b/src/apis/get-aliases.ts @@ -1,7 +1,9 @@ -import {Alias, PaginationResult} from "~/server-types" +import {AliasList, PaginationResult} from "~/server-types" import {client} from "~/constants/axios-client" -export default async function getAliases(): Promise> { +export default async function getAliases(): Promise< + PaginationResult +> { const {data} = await client.get( `${import.meta.env.VITE_SERVER_BASE_URL}/alias`, { diff --git a/src/apis/index.ts b/src/apis/index.ts index 140337f..d2f084d 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -30,3 +30,5 @@ export * from "./get-reports" export {default as getReports} from "./get-reports" export * from "./get-report" export {default as getReport} from "./get-report" +export * from "./get-alias" +export {default as getAlias} from "./get-alias" diff --git a/src/constants/enum_mappings.ts b/src/constants/enum_mappings.ts new file mode 100644 index 0000000..e49681f --- /dev/null +++ b/src/constants/enum_mappings.ts @@ -0,0 +1,22 @@ +import {ImageProxyFormatType, ProxyUserAgentType} from "~/server-types" + +export const IMAGE_PROXY_FORMAT_TYPE_NAME_MAP: Record< + ImageProxyFormatType, + string +> = { + [ImageProxyFormatType.JPEG]: "JPEG", + [ImageProxyFormatType.PNG]: "PNG", + [ImageProxyFormatType.WEBP]: "WebP", +} + +export const IMAGE_PROXY_USER_AGENT_TYPE_NAME_MAP: Record< + ProxyUserAgentType, + string +> = { + [ProxyUserAgentType.APPLE_MAIL]: "Apple Mail", + [ProxyUserAgentType.GOOGLE_MAIL]: "Google Mail", + [ProxyUserAgentType.CHROME]: "Chrome Browser", + [ProxyUserAgentType.FIREFOX]: "Firefox Browser", + [ProxyUserAgentType.OUTLOOK_MACOS]: "Outlook / MacOS", + [ProxyUserAgentType.OUTLOOK_WINDOWS]: "Outlook / Windows", +} diff --git a/src/route-widgets/AliasDetailRoute/AliasPreferencesForm.tsx b/src/route-widgets/AliasDetailRoute/AliasPreferencesForm.tsx new file mode 100644 index 0000000..96a0940 --- /dev/null +++ b/src/route-widgets/AliasDetailRoute/AliasPreferencesForm.tsx @@ -0,0 +1,140 @@ +import * as yup from "yup" +import {ReactElement} from "react" +import {BsImage, BsShieldShaded} from "react-icons/bs" +import {useFormik} from "formik" +import {FaFile} from "react-icons/fa" + +import {Collapse, Grid} from "@mui/material" +import {mdiTextBoxMultiple} from "@mdi/js/commonjs/mdi" +import Icon from "@mdi/react" + +import {Alias, ImageProxyFormatType, ProxyUserAgentType} from "~/server-types" +import {LoadingButton} from "@mui/lab" +import {MdCheckCircle} from "react-icons/md" +import SelectField from "~/route-widgets/SettingsRoute/SelectField" + +export interface AliasPreferencesFormProps { + alias: Alias +} + +interface Form { + removeTrackers: boolean + createMailReport: boolean + proxyImages: boolean + imageProxyFormat: ImageProxyFormatType + imageProxyUserAgent: ProxyUserAgentType + + detail?: string +} + +const SCHEMA = yup.object().shape({ + removeTrackers: yup.boolean(), + createMailReport: yup.boolean(), + proxyImages: yup.boolean(), + imageProxyFormat: yup + .mixed() + .oneOf(Object.values(ImageProxyFormatType)) + .required(), + imageProxyUserAgent: yup + .mixed() + .oneOf(Object.values(ProxyUserAgentType)) + .required(), +}) + +export default function AliasPreferencesForm({ + alias, +}: AliasPreferencesFormProps): ReactElement { + const formik = useFormik
({ + initialValues: { + removeTrackers: alias.prefRemoveTrackers, + createMailReport: alias.prefCreateMailReport, + proxyImages: alias.prefProxyImages, + imageProxyFormat: alias.prefImageProxyFormat, + imageProxyUserAgent: alias.prefImageProxyUserAgent, + }, + validationSchema: SCHEMA, + onSubmit: () => null, + }) + + return ( + + + + + + } + name="removeTrackers" + /> + + + + } + name="createMailReport" + /> + + + + + } + name="proxyImages" + /> + + + + + + } + name="imageProxyFormat" + /> + + + + + + + + + + + + + } + > + Save Settings + + + +
+ ) +} diff --git a/src/route-widgets/AliasRoute/AliasListItem.tsx b/src/route-widgets/AliasRoute/AliasListItem.tsx index 5ef9350..7d79198 100644 --- a/src/route-widgets/AliasRoute/AliasListItem.tsx +++ b/src/route-widgets/AliasRoute/AliasListItem.tsx @@ -3,7 +3,7 @@ import {MdOutlineMoreVert} from "react-icons/md" import { IconButton, - ListItem, + ListItemButton, ListItemSecondaryAction, ListItemText, } from "@mui/material" @@ -17,14 +17,16 @@ export interface AliasListItemProps { export default function AliasListItem({ alias, }: AliasListItemProps): ReactElement { + const address = `${alias.local}@${alias.domain}` + return ( - - + + - + ) } diff --git a/src/route-widgets/SettingsRoute/AliasesPreferencesForm.tsx b/src/route-widgets/SettingsRoute/AliasesPreferencesForm.tsx index a1e1d09..b0770db 100644 --- a/src/route-widgets/SettingsRoute/AliasesPreferencesForm.tsx +++ b/src/route-widgets/SettingsRoute/AliasesPreferencesForm.tsx @@ -30,6 +30,10 @@ import {UpdatePreferencesData, updatePreferences} from "~/apis" import {useUser} from "~/hooks" import {parseFastAPIError} from "~/utils" import {SuccessSnack} from "~/components" +import { + IMAGE_PROXY_FORMAT_TYPE_NAME_MAP, + IMAGE_PROXY_USER_AGENT_TYPE_NAME_MAP, +} from "~/constants/enum_mappings" import AuthContext from "~/AuthContext/AuthContext" import ErrorSnack from "~/components/ErrorSnack" @@ -57,22 +61,6 @@ const SCHEMA = yup.object().shape({ .required(), }) -const IMAGE_PROXY_FORMAT_TYPE_NAME_MAP: Record = { - [ImageProxyFormatType.JPEG]: "JPEG", - [ImageProxyFormatType.PNG]: "PNG", - [ImageProxyFormatType.WEBP]: "WebP", -} - -const IMAGE_PROXY_USER_AGENT_TYPE_NAME_MAP: Record = - { - [ProxyUserAgentType.APPLE_MAIL]: "Apple Mail", - [ProxyUserAgentType.GOOGLE_MAIL]: "Google Mail", - [ProxyUserAgentType.CHROME]: "Chrome Browser", - [ProxyUserAgentType.FIREFOX]: "Firefox Browser", - [ProxyUserAgentType.OUTLOOK_MACOS]: "Outlook / MacOS", - [ProxyUserAgentType.OUTLOOK_WINDOWS]: "Outlook / Windows", - } - export default function AliasesPreferencesForm(): ReactElement { const {_updateUser} = useContext(AuthContext) const user = useUser() diff --git a/src/route-widgets/SettingsRoute/SelectField.tsx b/src/route-widgets/SettingsRoute/SelectField.tsx new file mode 100644 index 0000000..59244f2 --- /dev/null +++ b/src/route-widgets/SettingsRoute/SelectField.tsx @@ -0,0 +1,64 @@ +import {ReactElement, ReactNode} from "react" + +import { + FormControl, + FormHelperText, + InputAdornment, + InputLabel, + MenuItem, + Select, +} from "@mui/material" + +export interface SelectFieldProps { + label: string + formik: any + name: string + + icon?: ReactElement + children?: ReactNode +} + +export default function SelectField({ + label, + formik, + icon, + name, + children, +}: SelectFieldProps): ReactElement { + const labelId = `${name}-label` + + return ( + + {label} + + + {formik.touched[name] && formik.errors[name]} + + + ) +} diff --git a/src/routes/AliasDetailRoute.tsx b/src/routes/AliasDetailRoute.tsx new file mode 100644 index 0000000..5fda109 --- /dev/null +++ b/src/routes/AliasDetailRoute.tsx @@ -0,0 +1,60 @@ +import {ReactElement} from "react" +import {useParams} from "react-router-dom" +import {AxiosError} from "axios" + +import {useQuery} from "@tanstack/react-query" +import {Grid, Typography} from "@mui/material" + +import {getAlias} from "~/apis" +import {Alias} from "~/server-types" +import AliasPreferencesForm from "~/route-widgets/AliasDetailRoute/AliasPreferencesForm" +import QueryResult from "~/components/QueryResult" + +export default function AliasDetailRoute(): ReactElement { + const params = useParams() + const address = atob(params.addressInBase64 as string) + + const query = useQuery( + ["get_alias", params.addressInBase64], + () => getAlias(address), + ) + + return ( + query={query}> + {alias => ( + + + + Alias Details + + + + {address} + + + + + Settings + + + + These settings apply to this alias only. You + can either set a value manually or refer to + your defaults settings. Note that this does + change in behavior. When you set a value to + refer to your default setting, the alias + will always use the latest value. So when + you change your default setting, the alias + will automatically use the new value. + + + + + + + + + )} + + ) +} diff --git a/src/server-types.ts b/src/server-types.ts index 61c31e9..7124f0a 100644 --- a/src/server-types.ts +++ b/src/server-types.ts @@ -82,11 +82,19 @@ export interface Alias { local: string isActive: boolean encryptedNotes: string - removeTrackers: boolean - createMailReport: boolean - proxyImages: boolean - imageProxyFormat: ImageProxyFormatType - imageProxyUserAgent: ProxyUserAgentType + + prefRemoveTrackers: boolean + prefCreateMailReport: boolean + prefProxyImages: boolean + prefImageProxyFormat: ImageProxyFormatType + prefImageProxyUserAgent: ProxyUserAgentType +} + +export interface AliasList { + id: string + domain: string + local: string + isActive: boolean } export interface Report {