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
+ )
+}
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 {