feat(dashboard,admin-shared): InjectionZones for Profile, Store, Users and Login (#7471)
This commit is contained in:
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>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in new issue
Block a user