feat(dashboard,admin-shared): InjectionZones for Profile, Store, Users and Login (#7471)

This commit is contained in:
Kasper Fabricius Kristensen authored and GitHub committed 2024-05-27 15:45:51 +00:00
1 parent 45bcdfec17
commit 81c27e3524
6 files changed
+147 -52

No files matched your search

@@ -82,6 +82,23 @@ const GIFT_CARD_INJECTION_ZONES = [
"custom_gift_card.after", "custom_gift_card.after",
] as const ] as const
const USER_INJECTION_ZONES = [
"user.details.before",
"user.details.after",
"user.list.before",
"user.list.after",
] as const
const STORE_INJECTION_ZONES = [
"store.details.before",
"store.details.after",
] as const
const PROFILE_INJECTION_ZONES = [
"profile.details.before",
"profile.details.after",
] as const
const REGION_INJECTION_ZONES = [ const REGION_INJECTION_ZONES = [
"region.details.before", "region.details.before",
"region.details.after", "region.details.after",
@@ -122,6 +139,9 @@ export const INJECTION_ZONES = [
...PRICE_LIST_INJECTION_ZONES, ...PRICE_LIST_INJECTION_ZONES,
...PROMOTION_INJECTION_ZONES, ...PROMOTION_INJECTION_ZONES,
...GIFT_CARD_INJECTION_ZONES, ...GIFT_CARD_INJECTION_ZONES,
...USER_INJECTION_ZONES,
...STORE_INJECTION_ZONES,
...PROFILE_INJECTION_ZONES,
...REGION_INJECTION_ZONES, ...REGION_INJECTION_ZONES,
...SHIPPING_PROFILE_INJECTION_ZONES, ...SHIPPING_PROFILE_INJECTION_ZONES,
...LOCATION_INJECTION_ZONES, ...LOCATION_INJECTION_ZONES,
@@ -5,11 +5,15 @@ import { Trans, useTranslation } from "react-i18next"
import { Link, useLocation, useNavigate } from "react-router-dom" import { Link, useLocation, useNavigate } from "react-router-dom"
import * as z from "zod" import * as z from "zod"
import { Divider } from "../../components/common/divider"
import { Form } from "../../components/common/form" import { Form } from "../../components/common/form"
import { LogoBox } from "../../components/common/logo-box" import { LogoBox } from "../../components/common/logo-box"
import { useEmailPassLogin } from "../../hooks/api/auth" import { useEmailPassLogin } from "../../hooks/api/auth"
import { isAxiosError } from "../../lib/is-axios-error" import { isAxiosError } from "../../lib/is-axios-error"
import after from "virtual:medusa/widgets/login/after"
import before from "virtual:medusa/widgets/login/before"
const LoginSchema = z.object({ const LoginSchema = z.object({
email: z.string().email(), email: z.string().email(),
password: z.string(), password: z.string(),
@@ -76,58 +80,74 @@ export const Login = () => {
{t("login.hint")} {t("login.hint")}
</Text> </Text>
</div> </div>
<Form {...form}> <div className="flex w-full flex-col gap-y-3">
<form {before.widgets.map((w, i) => {
onSubmit={handleSubmit} return (
className="flex w-full flex-col gap-y-6" <div key={i}>
> <w.Component />
<div className="flex flex-col gap-y-4"> </div>
<Form.Field )
control={form.control} })}
name="email" <Form {...form}>
render={({ field }) => { <form
return ( onSubmit={handleSubmit}
<Form.Item> className="flex w-full flex-col gap-y-6"
<Form.Label>{t("fields.email")}</Form.Label> >
<Form.Control> <div className="flex flex-col gap-y-4">
<Input autoComplete="email" {...field} /> <Form.Field
</Form.Control> control={form.control}
<Form.ErrorMessage /> name="email"
</Form.Item> render={({ field }) => {
) return (
}} <Form.Item>
/> <Form.Label>{t("fields.email")}</Form.Label>
<Form.Field <Form.Control>
control={form.control} <Input autoComplete="email" {...field} />
name="password" </Form.Control>
render={({ field }) => { <Form.ErrorMessage />
return ( </Form.Item>
<Form.Item> )
<Form.Label>{t("fields.password")}</Form.Label> }}
<Form.Control> />
<Input <Form.Field
type="password" control={form.control}
autoComplete="current-password" name="password"
{...field} render={({ field }) => {
/> return (
</Form.Control> <Form.Item>
<Form.ErrorMessage /> <Form.Label>{t("fields.password")}</Form.Label>
</Form.Item> <Form.Control>
) <Input
}} type="password"
/> autoComplete="current-password"
</div> {...field}
<Button className="w-full" type="submit" isLoading={isPending}> />
{t("actions.continue")} </Form.Control>
</Button> <Form.ErrorMessage />
</form> </Form.Item>
{serverError && ( )
<Alert className="mt-4" dismissible variant="error"> }}
{serverError} />
</Alert> </div>
)} <Button className="w-full" type="submit" isLoading={isPending}>
</Form> {t("actions.continue")}
<div className="my-6 h-px w-full border-b border-dotted" /> </Button>
</form>
{serverError && (
<Alert className="mt-4" dismissible variant="error">
{serverError}
</Alert>
)}
</Form>
{after.widgets.map((w, i) => {
return (
<div key={i}>
<w.Component />
</div>
)
})}
</div>
<Divider variant="dashed" className="my-6" />
<span className="text-ui-fg-subtle txt-small"> <span className="text-ui-fg-subtle txt-small">
<Trans <Trans
i18nKey="login.forgotPassword" i18nKey="login.forgotPassword"
@@ -1,7 +1,11 @@
import { Outlet, json } from "react-router-dom" import { Outlet, json } from "react-router-dom"
import { useMe } from "../../../hooks/api/users" import { useMe } from "../../../hooks/api/users"
import { ProfileGeneralSection } from "./components/profile-general-section" import { ProfileGeneralSection } from "./components/profile-general-section"
import after from "virtual:medusa/widgets/profile/details/after"
import before from "virtual:medusa/widgets/profile/details/before"
export const ProfileDetail = () => { export const ProfileDetail = () => {
const { user, isPending: isLoading, isError, error } = useMe() const { user, isPending: isLoading, isError, error } = useMe()
@@ -19,7 +23,17 @@ export const ProfileDetail = () => {
return ( return (
<div className="flex flex-col gap-y-2"> <div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => (
<div key={i}>
<w.Component data={user} />
</div>
))}
<ProfileGeneralSection user={user} /> <ProfileGeneralSection user={user} />
{after.widgets.map((w, i) => (
<div key={i}>
<w.Component data={user} />
</div>
))}
<Outlet /> <Outlet />
</div> </div>
) )
@@ -6,6 +6,9 @@ import { StoreCurrencySection } from "./components/store-currency-section/store-
import { StoreGeneralSection } from "./components/store-general-section/index.ts" import { StoreGeneralSection } from "./components/store-general-section/index.ts"
import { storeLoader } from "./loader.ts" import { storeLoader } from "./loader.ts"
import after from "virtual:medusa/widgets/store/details/after"
import before from "virtual:medusa/widgets/store/details/before"
export const StoreDetail = () => { export const StoreDetail = () => {
const initialData = useLoaderData() as Awaited<ReturnType<typeof storeLoader>> const initialData = useLoaderData() as Awaited<ReturnType<typeof storeLoader>>
@@ -28,8 +31,18 @@ export const StoreDetail = () => {
return ( return (
<div className="flex flex-col gap-y-2"> <div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => (
<div key={i}>
<w.Component data={store} />
</div>
))}
<StoreGeneralSection store={store} /> <StoreGeneralSection store={store} />
<StoreCurrencySection store={store} /> <StoreCurrencySection store={store} />
{after.widgets.map((w, i) => (
<div key={i}>
<w.Component data={store} />
</div>
))}
<JsonViewSection data={store} /> <JsonViewSection data={store} />
<Outlet /> <Outlet />
</div> </div>
@@ -1,9 +1,13 @@
import { Outlet, json, useLoaderData, useParams } from "react-router-dom" import { Outlet, json, useLoaderData, useParams } from "react-router-dom"
import { JsonViewSection } from "../../../components/common/json-view-section" import { JsonViewSection } from "../../../components/common/json-view-section"
import { useUser } from "../../../hooks/api/users" import { useUser } from "../../../hooks/api/users"
import { UserGeneralSection } from "./components/user-general-section" import { UserGeneralSection } from "./components/user-general-section"
import { userLoader } from "./loader" import { userLoader } from "./loader"
import after from "virtual:medusa/widgets/user/details/after"
import before from "virtual:medusa/widgets/user/details/before"
export const UserDetail = () => { export const UserDetail = () => {
const initialData = useLoaderData() as Awaited<ReturnType<typeof userLoader>> const initialData = useLoaderData() as Awaited<ReturnType<typeof userLoader>>
@@ -31,7 +35,17 @@ export const UserDetail = () => {
return ( return (
<div className="flex flex-col gap-y-2"> <div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => (
<div key={i}>
<w.Component data={user} />
</div>
))}
<UserGeneralSection user={user} /> <UserGeneralSection user={user} />
{after.widgets.map((w, i) => (
<div key={i}>
<w.Component data={user} />
</div>
))}
<JsonViewSection data={user} /> <JsonViewSection data={user} />
<Outlet /> <Outlet />
</div> </div>
@@ -1,10 +1,24 @@
import { Outlet } from "react-router-dom" import { Outlet } from "react-router-dom"
import { UserListTable } from "./components/user-list-table" import { UserListTable } from "./components/user-list-table"
import after from "virtual:medusa/widgets/user/list/after"
import before from "virtual:medusa/widgets/user/list/before"
export const UserList = () => { export const UserList = () => {
return ( return (
<div className="flex flex-col gap-y-2"> <div className="flex flex-col gap-y-2">
{before.widgets.map((w, i) => (
<div key={i}>
<w.Component />
</div>
))}
<UserListTable /> <UserListTable />
{after.widgets.map((w, i) => (
<div key={i}>
<w.Component />
</div>
))}
<Outlet /> <Outlet />
</div> </div>
) )