gitscope
← marzneshin / Diff · d636f3f → d636f3f
Changes d636f3f..d636f3f
Patch commit
diff --git a/app/db/crud.py b/app/db/crud.py
index 35de70d..417106e 100644
--- a/app/db/crud.py
+++ b/app/db/crud.py
@@ -184,6 +184,10 @@ def add_host(db: Session, inbound: Inbound, host: InboundHostModify):
alpn=host.alpn.value,
fingerprint=host.fingerprint,
fragment=host.fragment.model_dump() if host.fragment else None,
+ udp_noises=host.udp_noises,
+ http_headers=host.http_headers,
+ mtu=host.mtu,
+ dns_servers=host.dns_servers,
mux=host.mux,
allowinsecure=host.allowinsecure,
weight=host.weight,
@@ -208,6 +212,10 @@ def update_host(db: Session, db_host: InboundHost, host: InboundHostModify):
db_host.mux = host.mux
db_host.is_disabled = host.is_disabled
db_host.allowinsecure = host.allowinsecure
+ db_host.udp_noises = host.udp_noises
+ db_host.http_headers = host.http_headers
+ db_host.mtu = host.mtu
+ db_host.dns_servers = host.dns_servers
db_host.weight = host.weight
db.commit()
db.refresh(db_host)
diff --git a/app/db/migrations/versions/c97bd32e6e12_add_noises_to_hosts.py b/app/db/migrations/versions/c97bd32e6e12_add_noises_to_hosts.py
new file mode 100644
index 0000000..30d1dcf
--- /dev/null
+++ b/app/db/migrations/versions/c97bd32e6e12_add_noises_to_hosts.py
@@ -0,0 +1,36 @@
+"""add noises to hosts
+
+Revision ID: c97bd32e6e12
+Revises: b613375d2fca
+Create Date: 2024-11-03 03:47:00.293632
+
+"""
+
+import sqlalchemy as sa
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "c97bd32e6e12"
+down_revision = "b613375d2fca"
+branch_labels = None
+depends_on = None
+
+
+def upgrade() -> None:
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.add_column("hosts", sa.Column("udp_noises", sa.JSON(), nullable=True))
+ op.add_column("hosts", sa.Column("http_headers", sa.JSON(), nullable=True))
+ op.add_column(
+ "hosts", sa.Column("dns_servers", sa.String(length=128), nullable=True)
+ )
+ op.add_column("hosts", sa.Column("mtu", sa.Integer(), nullable=True))
+ # ### end Alembic commands ###
+
+
+def downgrade() -> None:
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.drop_column("hosts", "mtu")
+ op.drop_column("hosts", "dns_servers")
+ op.drop_column("hosts", "http_headers")
+ op.drop_column("hosts", "udp_noises")
+ # ### end Alembic commands ###
diff --git a/app/db/models.py b/app/db/models.py
index 40bee45..ebe261c 100644
--- a/app/db/models.py
+++ b/app/db/models.py
@@ -346,13 +346,20 @@ class InboundHost(Base):
server_default=sqlalchemy.sql.false(),
)
fragment = Column(JSON())
-
+ udp_noises = Column(JSON())
+ http_headers = Column(JSON())
+ dns_servers = Column(String(128))
+ mtu = Column(Integer)
inbound_id = Column(Integer, ForeignKey("inbounds.id"), nullable=False)
- inbound = relationship("Inbound", back_populates="hosts")
+ inbound = relationship("Inbound", back_populates="hosts", lazy="joined")
allowinsecure = Column(Boolean, default=False)
is_disabled = Column(Boolean, default=False)
weight = Column(Integer, default=1, nullable=False, server_default="1")
+ @property
+ def protocol(self):
+ return self.inbound.protocol if self.inbound else None
+
class System(Base):
__tablename__ = "system"
diff --git a/app/models/proxy.py b/app/models/proxy.py
index b1a64d7..6649181 100644
--- a/app/models/proxy.py
+++ b/app/models/proxy.py
@@ -66,6 +66,12 @@ class FragmentSettings(BaseModel):
interval: str = Field(pattern=r"^[\d-]{1,32}$")
+class UDPNoiseSettings(BaseModel):
+ type: str = Field(pattern=r"^(:?rand|str|base64)$")
+ packet: str = Field()
+ interval: str = Field(pattern=r"^[\d-]{1,32}$")
+
+
class InboundHost(BaseModel):
remark: str
address: str
@@ -76,11 +82,17 @@ class InboundHost(BaseModel):
security: InboundHostSecurity = InboundHostSecurity.inbound_default
alpn: InboundHostALPN = InboundHostALPN.none
fingerprint: InboundHostFingerprint = InboundHostFingerprint.none
- allowinsecure: bool | None = None
- is_disabled: bool | None = None
+ allowinsecure: bool | None = False
+ is_disabled: bool | None = False
mux: bool = Field(False)
fragment: FragmentSettings | None = Field(None)
+ udp_noises: list[UDPNoiseSettings] | None = []
+ http_headers: dict[str, list[str]] | None = {}
+ mtu: int | None = None
+ dns_servers: str | None = None
weight: int = 1
+ protocol: ProxyTypes | None = None
+ inbound_id: int | None = None
model_config = ConfigDict(from_attributes=True)
@field_validator("remark", "address", "path")
diff --git a/app/utils/share.py b/app/utils/share.py
index fc4f5e6..c7538e7 100644
--- a/app/utils/share.py
+++ b/app/utils/share.py
@@ -299,6 +299,10 @@ def generate_user_configs(
inbound.get("address"), user_id
),
flow=inbound.get("flow"),
+ dns_servers=(
+ host.dns_servers.split(",") if host.dns_servers else []
+ ),
+ mtu=host.mtu,
allow_insecure=host.allowinsecure,
uuid=UUID(gen_uuid(key)),
password=gen_password(key),
diff --git a/dashboard/public/locales/en.json b/dashboard/public/locales/en.json
index 5695d75..c82335a 100644
--- a/dashboard/public/locales/en.json
+++ b/dashboard/public/locales/en.json
@@ -266,6 +266,13 @@
"users-data-usage": "Users Data Usage"
},
"hosts": {
+ "dns-servers": "DNS Servers",
+ "obfuscation-password": "Obfuscation Password",
+ "server-public-key": "Server public key",
+ "tls-config": "TLS Config",
+ "network-settings": "Network Settings",
+ "security-settings": "Security Settings",
+ "camouflage-settings": "Camouflage Settings",
"fragment": {
"interval": "Interval",
"length": "Length",
diff --git a/dashboard/src/hooks/index.ts b/dashboard/src/common/hooks/index.ts
similarity index 100%
rename from dashboard/src/hooks/index.ts
rename to dashboard/src/common/hooks/index.ts
diff --git a/dashboard/src/hooks/use-dialog.ts b/dashboard/src/common/hooks/use-dialog.ts
similarity index 100%
rename from dashboard/src/hooks/use-dialog.ts
rename to dashboard/src/common/hooks/use-dialog.ts
diff --git a/dashboard/src/hooks/use-is-current-route.ts b/dashboard/src/common/hooks/use-is-current-route.ts
similarity index 100%
rename from dashboard/src/hooks/use-is-current-route.ts
rename to dashboard/src/common/hooks/use-is-current-route.ts
diff --git a/dashboard/src/hooks/use-mutation-dialog/index.ts b/dashboard/src/common/hooks/use-mutation-dialog/index.ts
similarity index 98%
rename from dashboard/src/hooks/use-mutation-dialog/index.ts
rename to dashboard/src/common/hooks/use-mutation-dialog/index.ts
index eda8209..3cf2f43 100644
--- a/dashboard/src/hooks/use-mutation-dialog/index.ts
+++ b/dashboard/src/common/hooks/use-mutation-dialog/index.ts
@@ -1,4 +1,4 @@
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
import { zodResolver } from "@hookform/resolvers/zod";
import { UseMutationResult } from "@tanstack/react-query";
import { useEffect } from "react";
diff --git a/dashboard/src/hooks/use-screen-breakpoint.ts b/dashboard/src/common/hooks/use-screen-breakpoint.ts
similarity index 100%
rename from dashboard/src/hooks/use-screen-breakpoint.ts
rename to dashboard/src/common/hooks/use-screen-breakpoint.ts
diff --git a/dashboard/src/types/index.ts b/dashboard/src/common/types/index.ts
similarity index 100%
rename from dashboard/src/types/index.ts
rename to dashboard/src/common/types/index.ts
diff --git a/dashboard/src/types/routes.ts b/dashboard/src/common/types/routes.ts
similarity index 100%
rename from dashboard/src/types/routes.ts
rename to dashboard/src/common/types/routes.ts
diff --git a/dashboard/src/types/status.ts b/dashboard/src/common/types/status.ts
similarity index 100%
rename from dashboard/src/types/status.ts
rename to dashboard/src/common/types/status.ts
diff --git a/dashboard/src/utils/cn.ts b/dashboard/src/common/utils/cn.ts
similarity index 100%
rename from dashboard/src/utils/cn.ts
rename to dashboard/src/common/utils/cn.ts
diff --git a/dashboard/src/utils/color-generator.ts b/dashboard/src/common/utils/color-generator.ts
similarity index 100%
rename from dashboard/src/utils/color-generator.ts
rename to dashboard/src/common/utils/color-generator.ts
diff --git a/dashboard/src/utils/compose-refs.ts b/dashboard/src/common/utils/compose-refs.ts
similarity index 100%
rename from dashboard/src/utils/compose-refs.ts
rename to dashboard/src/common/utils/compose-refs.ts
diff --git a/dashboard/src/utils/fetch.ts b/dashboard/src/common/utils/fetch.ts
similarity index 100%
rename from dashboard/src/utils/fetch.ts
rename to dashboard/src/common/utils/fetch.ts
diff --git a/dashboard/src/utils/index.ts b/dashboard/src/common/utils/index.ts
similarity index 100%
rename from dashboard/src/utils/index.ts
rename to dashboard/src/common/utils/index.ts
diff --git a/dashboard/src/utils/project-info.ts b/dashboard/src/common/utils/project-info.ts
similarity index 100%
rename from dashboard/src/utils/project-info.ts
rename to dashboard/src/common/utils/project-info.ts
diff --git a/dashboard/src/utils/query-client.ts b/dashboard/src/common/utils/query-client.ts
similarity index 100%
rename from dashboard/src/utils/query-client.ts
rename to dashboard/src/common/utils/query-client.ts
diff --git a/dashboard/src/utils/subscription-link.ts b/dashboard/src/common/utils/subscription-link.ts
similarity index 100%
rename from dashboard/src/utils/subscription-link.ts
rename to dashboard/src/common/utils/subscription-link.ts
diff --git a/dashboard/src/components/copy-button/index.tsx b/dashboard/src/components/copy-button/index.tsx
index 72db482..cd4890f 100644
--- a/dashboard/src/components/copy-button/index.tsx
+++ b/dashboard/src/components/copy-button/index.tsx
@@ -9,7 +9,7 @@ import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { CopyCheck, CopyX, ClipboardCopy, LucideIcon } from "lucide-react";
import { toast } from "sonner";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
interface CopyToClipboardButtonProps {
text: string;
diff --git a/dashboard/src/components/form-fields/date.tsx b/dashboard/src/components/form-fields/date.tsx
index 2afa0b8..bbca968 100644
--- a/dashboard/src/components/form-fields/date.tsx
+++ b/dashboard/src/components/form-fields/date.tsx
@@ -1,7 +1,7 @@
import { type FC, useEffect, useState } from "react";
import { format } from "date-fns";
import { CalendarIcon } from "@radix-ui/react-icons";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { useFormContext, type FieldValues } from "react-hook-form";
import { useTranslation } from "react-i18next";
import {
diff --git a/dashboard/src/components/header/menu.tsx b/dashboard/src/components/header/menu.tsx
index d712045..fb84540 100644
--- a/dashboard/src/components/header/menu.tsx
+++ b/dashboard/src/components/header/menu.tsx
@@ -14,7 +14,7 @@ import { Settings, MenuIcon, ShieldCheck } from "lucide-react";
import { LanguageSwitchMenu } from "@marzneshin/features/language-switch";
import { ThemeToggle } from "@marzneshin/features/theme-switch";
import { useAuth, Logout } from "@marzneshin/features/auth";
-import { useScreenBreakpoint } from "@marzneshin/hooks/use-screen-breakpoint";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks/use-screen-breakpoint";
import { useTranslation } from "react-i18next";
export const HeaderMenu: FC = () => {
diff --git a/dashboard/src/components/nav-dir/index.tsx b/dashboard/src/components/nav-dir/index.tsx
index 9c27f79..d20759e 100644
--- a/dashboard/src/components/nav-dir/index.tsx
+++ b/dashboard/src/components/nav-dir/index.tsx
@@ -24,8 +24,8 @@ import {
Button,
SidebarObject,
} from "@marzneshin/components"
-import { useScreenBreakpoint } from "@marzneshin/hooks/use-screen-breakpoint";
-import { AppRouterPaths } from "@marzneshin/types";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks";
+import { AppRouterPaths } from "@marzneshin/common/types";
import i18n from "@marzneshin/features/i18n";
interface Dir {
diff --git a/dashboard/src/components/page/index.tsx b/dashboard/src/components/page/index.tsx
index 5bba518..28ba2dd 100644
--- a/dashboard/src/components/page/index.tsx
+++ b/dashboard/src/components/page/index.tsx
@@ -7,7 +7,7 @@ import {
CardHeader,
CardTitle,
} from '@marzneshin/components';
-import { cn } from '@marzneshin/utils';
+import { cn } from '@marzneshin/common/utils';
interface PageProps {
title: JSX.Element | string;
diff --git a/dashboard/src/components/sidebar/sidebar-body.tsx b/dashboard/src/components/sidebar/sidebar-body.tsx
index d1cba12..9e239ca 100644
--- a/dashboard/src/components/sidebar/sidebar-body.tsx
+++ b/dashboard/src/components/sidebar/sidebar-body.tsx
@@ -1,4 +1,4 @@
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { FC, PropsWithChildren } from "react"
export interface SidebarBodyProps
diff --git a/dashboard/src/components/sidebar/sidebar-group.tsx b/dashboard/src/components/sidebar/sidebar-group.tsx
index cf56d87..1ba7c8f 100644
--- a/dashboard/src/components/sidebar/sidebar-group.tsx
+++ b/dashboard/src/components/sidebar/sidebar-group.tsx
@@ -1,7 +1,7 @@
import { FC, PropsWithChildren } from "react"
import { Label } from "@marzneshin/components"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { useSidebarContext } from "./sidebar-provider";
export interface SidebarGroupProps
diff --git a/dashboard/src/components/sidebar/sidebar-header.tsx b/dashboard/src/components/sidebar/sidebar-header.tsx
index 3d71bbd..85d1093 100644
--- a/dashboard/src/components/sidebar/sidebar-header.tsx
+++ b/dashboard/src/components/sidebar/sidebar-header.tsx
@@ -1,4 +1,4 @@
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { FC, PropsWithChildren } from "react"
export interface SidebarHeaderProps extends
diff --git a/dashboard/src/components/sidebar/sidebar-item.tsx b/dashboard/src/components/sidebar/sidebar-item.tsx
index 07e474a..1401cd1 100644
--- a/dashboard/src/components/sidebar/sidebar-item.tsx
+++ b/dashboard/src/components/sidebar/sidebar-item.tsx
@@ -1,7 +1,7 @@
import { Link } from "@tanstack/react-router";
import type { FC } from "react";
import type { SidebarItem as SidebarItemType } from "./types";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { type VariantProps, cva } from "class-variance-authority";
import { useSidebarContext } from "./sidebar-provider";
diff --git a/dashboard/src/components/sidebar/sidebar.tsx b/dashboard/src/components/sidebar/sidebar.tsx
index 87b6447..8da775f 100644
--- a/dashboard/src/components/sidebar/sidebar.tsx
+++ b/dashboard/src/components/sidebar/sidebar.tsx
@@ -3,7 +3,7 @@ import { useMemo } from "react";
import { SidebarContext } from "./sidebar-provider";
import type { SidebarItemGroup } from "./types";
import { type VariantProps, cva } from "class-variance-authority";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { SidebarHeader } from "./sidebar-header";
import { SidebarFooter } from "./sidebar-footer";
import { SidebarBody } from "./sidebar-body";
@@ -11,53 +11,53 @@ import { SidebarItem } from "./sidebar-item";
import { SidebarGroup } from "./sidebar-group";
const sidebarVariants = cva("flex flex-col justify-between h-full w-full", {
- variants: {
- variant: {
- default: "",
+ variants: {
+ variant: {
+ default: "",
+ },
},
- },
});
interface ContentComposition {
- Header: typeof SidebarHeader;
- Footer: typeof SidebarFooter;
- Body: typeof SidebarBody;
- Group: typeof SidebarGroup;
- Item: typeof SidebarItem;
+ Header: typeof SidebarHeader;
+ Footer: typeof SidebarFooter;
+ Body: typeof SidebarBody;
+ Group: typeof SidebarGroup;
+ Item: typeof SidebarItem;
}
export interface SidebarProps
- extends React.HTMLAttributes<HTMLDivElement>,
+ extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof sidebarVariants> {
- sidebar: SidebarItemGroup;
- collapsed: boolean;
- setCollapsed: (state: boolean) => void;
- open?: boolean;
- setOpen?: (state: boolean) => void;
+ sidebar: SidebarItemGroup;
+ collapsed: boolean;
+ setCollapsed: (state: boolean) => void;
+ open?: boolean;
+ setOpen?: (state: boolean) => void;
}
const Sidebar: FC<SidebarProps & PropsWithChildren> & ContentComposition = ({
- collapsed,
- setCollapsed,
- sidebar,
- variant,
- className,
- setOpen,
- open,
- children,
- ...props
+ collapsed,
+ setCollapsed,
+ sidebar,
+ variant,
+ className,
+ setOpen,
+ open,
+ children,
+ ...props
}) => {
- const contextValue = useMemo(
- () => ({ sidebar, collapsed, setCollapsed, open, setOpen }),
- [sidebar, collapsed, setCollapsed, open, setOpen],
- );
- return (
- <SidebarContext.Provider value={contextValue}>
- <div className={cn(sidebarVariants({ variant, className }))} {...props}>
- {children}
- </div>
- </SidebarContext.Provider>
- );
+ const contextValue = useMemo(
+ () => ({ sidebar, collapsed, setCollapsed, open, setOpen }),
+ [sidebar, collapsed, setCollapsed, open, setOpen],
+ );
+ return (
+ <SidebarContext.Provider value={contextValue}>
+ <div className={cn(sidebarVariants({ variant, className }))} {...props}>
+ {children}
+ </div>
+ </SidebarContext.Provider>
+ );
};
Sidebar.Header = SidebarHeader;
diff --git a/dashboard/src/components/sidebar/types.ts b/dashboard/src/components/sidebar/types.ts
index 4b5b325..ebedc1c 100644
--- a/dashboard/src/components/sidebar/types.ts
+++ b/dashboard/src/components/sidebar/types.ts
@@ -1,7 +1,6 @@
-import { AppRouterPaths } from "@marzneshin/types";
+import { AppRouterPaths } from "@marzneshin/common/types";
import { ReactNode } from "react";
-
export interface SidebarItem {
title: string;
to: AppRouterPaths;
diff --git a/dashboard/src/components/stacks/horizontal.tsx b/dashboard/src/components/stacks/horizontal.tsx
index fa7f8bc..d7516a6 100644
--- a/dashboard/src/components/stacks/horizontal.tsx
+++ b/dashboard/src/components/stacks/horizontal.tsx
@@ -1,9 +1,9 @@
import type { FC, PropsWithChildren, HTMLAttributes } from "react";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
export const HStack: FC<PropsWithChildren & HTMLAttributes<HTMLDivElement>> = ({
- children,
- className,
+ children,
+ className,
}) => {
- return <div className={cn("flex flex-row gap-2", className)}>{children}</div>;
+ return <div className={cn("flex flex-row gap-2", className)}>{children}</div>;
};
diff --git a/dashboard/src/components/stacks/vertical.tsx b/dashboard/src/components/stacks/vertical.tsx
index 6c7251f..ed31773 100644
--- a/dashboard/src/components/stacks/vertical.tsx
+++ b/dashboard/src/components/stacks/vertical.tsx
@@ -1,14 +1,14 @@
import type { FC, PropsWithChildren, HTMLAttributes } from "react";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
export const VStack: FC<PropsWithChildren & HTMLAttributes<HTMLDivElement>> = ({
- children,
- className,
- ...props
+ children,
+ className,
+ ...props
}) => {
- return (
- <div className={cn("flex flex-col gap-2", className)} {...props}>
- {children}
- </div>
- );
+ return (
+ <div className={cn("flex flex-col gap-2", className)} {...props}>
+ {children}
+ </div>
+ );
};
diff --git a/dashboard/src/components/ui/accordion.tsx b/dashboard/src/components/ui/accordion.tsx
index 2075990..56d9648 100644
--- a/dashboard/src/components/ui/accordion.tsx
+++ b/dashboard/src/components/ui/accordion.tsx
@@ -2,53 +2,53 @@ import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDown } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Accordion = AccordionPrimitive.Root
const AccordionItem = React.forwardRef<
- React.ElementRef<typeof AccordionPrimitive.Item>,
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
+ React.ElementRef<typeof AccordionPrimitive.Item>,
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
- <AccordionPrimitive.Item
- ref={ref}
- className={cn("border-b", className)}
- {...props}
- />
+ <AccordionPrimitive.Item
+ ref={ref}
+ className={cn("border-b", className)}
+ {...props}
+ />
))
AccordionItem.displayName = "AccordionItem"
const AccordionTrigger = React.forwardRef<
- React.ElementRef<typeof AccordionPrimitive.Trigger>,
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
+ React.ElementRef<typeof AccordionPrimitive.Trigger>,
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
- <AccordionPrimitive.Header className="flex">
- <AccordionPrimitive.Trigger
- ref={ref}
- className={cn(
- "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
- className
- )}
- {...props}
- >
- {children}
- <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
- </AccordionPrimitive.Trigger>
- </AccordionPrimitive.Header>
+ <AccordionPrimitive.Header className="flex">
+ <AccordionPrimitive.Trigger
+ ref={ref}
+ className={cn(
+ "flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
+ className
+ )}
+ {...props}
+ >
+ {children}
+ <ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
+ </AccordionPrimitive.Trigger>
+ </AccordionPrimitive.Header>
))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
const AccordionContent = React.forwardRef<
- React.ElementRef<typeof AccordionPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
+ React.ElementRef<typeof AccordionPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
- <AccordionPrimitive.Content
- ref={ref}
- className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
- {...props}
- >
- <div className={cn("pb-4 pt-0", className)}>{children}</div>
- </AccordionPrimitive.Content>
+ <AccordionPrimitive.Content
+ ref={ref}
+ className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
+ {...props}
+ >
+ <div className={cn("pb-4 pt-0", className)}>{children}</div>
+ </AccordionPrimitive.Content>
))
AccordionContent.displayName = AccordionPrimitive.Content.displayName
diff --git a/dashboard/src/components/ui/alert-dialog.tsx b/dashboard/src/components/ui/alert-dialog.tsx
index 6738d8f..1e66674 100644
--- a/dashboard/src/components/ui/alert-dialog.tsx
+++ b/dashboard/src/components/ui/alert-dialog.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { buttonVariants } from "@marzneshin/components/ui/button"
const AlertDialog = AlertDialogPrimitive.Root
@@ -11,129 +11,129 @@ const AlertDialogTrigger = AlertDialogPrimitive.Trigger
const AlertDialogPortal = AlertDialogPrimitive.Portal
const AlertDialogOverlay = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
+ React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
- <AlertDialogPrimitive.Overlay
- className={cn(
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
- className
- )}
- {...props}
- ref={ref}
- />
+ <AlertDialogPrimitive.Overlay
+ className={cn(
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
+ className
+ )}
+ {...props}
+ ref={ref}
+ />
))
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
const AlertDialogContent = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
+ React.ElementRef<typeof AlertDialogPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
>(({ className, ...props }, ref) => (
- <AlertDialogPortal>
- <AlertDialogOverlay />
- <AlertDialogPrimitive.Content
- ref={ref}
- className={cn(
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
- className
- )}
- {...props}
- />
- </AlertDialogPortal>
+ <AlertDialogPortal>
+ <AlertDialogOverlay />
+ <AlertDialogPrimitive.Content
+ ref={ref}
+ className={cn(
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
+ className
+ )}
+ {...props}
+ />
+ </AlertDialogPortal>
))
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
const AlertDialogHeader = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col space-y-2 text-center sm:text-left",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col space-y-2 text-center sm:text-left",
+ className
+ )}
+ {...props}
+ />
)
AlertDialogHeader.displayName = "AlertDialogHeader"
const AlertDialogFooter = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
+ className
+ )}
+ {...props}
+ />
)
AlertDialogFooter.displayName = "AlertDialogFooter"
const AlertDialogTitle = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Title>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
+ React.ElementRef<typeof AlertDialogPrimitive.Title>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
>(({ className, ...props }, ref) => (
- <AlertDialogPrimitive.Title
- ref={ref}
- className={cn("text-lg font-semibold", className)}
- {...props}
- />
+ <AlertDialogPrimitive.Title
+ ref={ref}
+ className={cn("text-lg font-semibold", className)}
+ {...props}
+ />
))
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
const AlertDialogDescription = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Description>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
+ React.ElementRef<typeof AlertDialogPrimitive.Description>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
>(({ className, ...props }, ref) => (
- <AlertDialogPrimitive.Description
- ref={ref}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
+ <AlertDialogPrimitive.Description
+ ref={ref}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
AlertDialogDescription.displayName =
- AlertDialogPrimitive.Description.displayName
+ AlertDialogPrimitive.Description.displayName
const AlertDialogAction = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Action>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
+ React.ElementRef<typeof AlertDialogPrimitive.Action>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
>(({ className, ...props }, ref) => (
- <AlertDialogPrimitive.Action
- ref={ref}
- className={cn(buttonVariants(), className)}
- {...props}
- />
+ <AlertDialogPrimitive.Action
+ ref={ref}
+ className={cn(buttonVariants(), className)}
+ {...props}
+ />
))
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
const AlertDialogCancel = React.forwardRef<
- React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
+ React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
>(({ className, ...props }, ref) => (
- <AlertDialogPrimitive.Cancel
- ref={ref}
- className={cn(
- buttonVariants({ variant: "outline" }),
- "mt-2 sm:mt-0",
- className
- )}
- {...props}
- />
+ <AlertDialogPrimitive.Cancel
+ ref={ref}
+ className={cn(
+ buttonVariants({ variant: "outline" }),
+ "mt-2 sm:mt-0",
+ className
+ )}
+ {...props}
+ />
))
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
export {
- AlertDialog,
- AlertDialogPortal,
- AlertDialogOverlay,
- AlertDialogTrigger,
- AlertDialogContent,
- AlertDialogHeader,
- AlertDialogFooter,
- AlertDialogTitle,
- AlertDialogDescription,
- AlertDialogAction,
- AlertDialogCancel,
+ AlertDialog,
+ AlertDialogPortal,
+ AlertDialogOverlay,
+ AlertDialogTrigger,
+ AlertDialogContent,
+ AlertDialogHeader,
+ AlertDialogFooter,
+ AlertDialogTitle,
+ AlertDialogDescription,
+ AlertDialogAction,
+ AlertDialogCancel,
}
diff --git a/dashboard/src/components/ui/alert.tsx b/dashboard/src/components/ui/alert.tsx
index 9f22b3a..cf2e03c 100644
--- a/dashboard/src/components/ui/alert.tsx
+++ b/dashboard/src/components/ui/alert.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const alertVariants = cva(
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
diff --git a/dashboard/src/components/ui/badge.tsx b/dashboard/src/components/ui/badge.tsx
index 88a7db5..ad438d6 100644
--- a/dashboard/src/components/ui/badge.tsx
+++ b/dashboard/src/components/ui/badge.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
diff --git a/dashboard/src/components/ui/breadcrumb.tsx b/dashboard/src/components/ui/breadcrumb.tsx
index 06bc3f6..c0186ad 100644
--- a/dashboard/src/components/ui/breadcrumb.tsx
+++ b/dashboard/src/components/ui/breadcrumb.tsx
@@ -2,114 +2,114 @@ import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Breadcrumb = React.forwardRef<
- HTMLElement,
- React.ComponentPropsWithoutRef<"nav"> & {
- separator?: React.ReactNode
- }
+ HTMLElement,
+ React.ComponentPropsWithoutRef<"nav"> & {
+ separator?: React.ReactNode
+ }
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
Breadcrumb.displayName = "Breadcrumb"
const BreadcrumbList = React.forwardRef<
- HTMLOListElement,
- React.ComponentPropsWithoutRef<"ol">
+ HTMLOListElement,
+ React.ComponentPropsWithoutRef<"ol">
>(({ className, ...props }, ref) => (
- <ol
- ref={ref}
- className={cn(
- "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
- className
- )}
- {...props}
- />
+ <ol
+ ref={ref}
+ className={cn(
+ "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
+ className
+ )}
+ {...props}
+ />
))
BreadcrumbList.displayName = "BreadcrumbList"
const BreadcrumbItem = React.forwardRef<
- HTMLLIElement,
- React.ComponentPropsWithoutRef<"li">
+ HTMLLIElement,
+ React.ComponentPropsWithoutRef<"li">
>(({ className, ...props }, ref) => (
- <li
- ref={ref}
- className={cn("inline-flex items-center gap-1.5", className)}
- {...props}
- />
+ <li
+ ref={ref}
+ className={cn("inline-flex items-center gap-1.5", className)}
+ {...props}
+ />
))
BreadcrumbItem.displayName = "BreadcrumbItem"
const BreadcrumbLink = React.forwardRef<
- HTMLAnchorElement,
- React.ComponentPropsWithoutRef<"a"> & {
- asChild?: boolean
- }
+ HTMLAnchorElement,
+ React.ComponentPropsWithoutRef<"a"> & {
+ asChild?: boolean
+ }
>(({ asChild, className, ...props }, ref) => {
- const Comp = asChild ? Slot : "a"
+ const Comp = asChild ? Slot : "a"
- return (
- <Comp
- ref={ref}
- className={cn("transition-colors hover:text-foreground", className)}
- {...props}
- />
- )
+ return (
+ <Comp
+ ref={ref}
+ className={cn("transition-colors hover:text-foreground", className)}
+ {...props}
+ />
+ )
})
BreadcrumbLink.displayName = "BreadcrumbLink"
const BreadcrumbPage = React.forwardRef<
- HTMLSpanElement,
- React.ComponentPropsWithoutRef<"span">
+ HTMLSpanElement,
+ React.ComponentPropsWithoutRef<"span">
>(({ className, ...props }, ref) => (
- <span
- ref={ref}
- role="link"
- aria-disabled="true"
- aria-current="page"
- className={cn("font-normal text-foreground", className)}
- {...props}
- />
+ <span
+ ref={ref}
+ role="link"
+ aria-disabled="true"
+ aria-current="page"
+ className={cn("font-normal text-foreground", className)}
+ {...props}
+ />
))
BreadcrumbPage.displayName = "BreadcrumbPage"
const BreadcrumbSeparator = ({
- children,
- className,
- ...props
+ children,
+ className,
+ ...props
}: React.ComponentProps<"li">) => (
- <li
- role="presentation"
- aria-hidden="true"
- className={cn("[&>svg]:size-3.5", className)}
- {...props}
- >
- {children ?? <ChevronRight />}
- </li>
+ <li
+ role="presentation"
+ aria-hidden="true"
+ className={cn("[&>svg]:size-3.5", className)}
+ {...props}
+ >
+ {children ?? <ChevronRight />}
+ </li>
)
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
const BreadcrumbEllipsis = ({
- className,
- ...props
+ className,
+ ...props
}: React.ComponentProps<"span">) => (
- <span
- role="presentation"
- aria-hidden="true"
- className={cn("flex h-9 w-9 items-center justify-center", className)}
- {...props}
- >
- <MoreHorizontal className="h-4 w-4" />
- <span className="sr-only">More</span>
- </span>
+ <span
+ role="presentation"
+ aria-hidden="true"
+ className={cn("flex h-9 w-9 items-center justify-center", className)}
+ {...props}
+ >
+ <MoreHorizontal className="h-4 w-4" />
+ <span className="sr-only">More</span>
+ </span>
)
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
export {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
- BreadcrumbEllipsis,
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+ BreadcrumbEllipsis,
}
diff --git a/dashboard/src/components/ui/button/index.tsx b/dashboard/src/components/ui/button/index.tsx
index 5c09ea0..3986677 100644
--- a/dashboard/src/components/ui/button/index.tsx
+++ b/dashboard/src/components/ui/button/index.tsx
@@ -2,7 +2,7 @@ import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
diff --git a/dashboard/src/components/ui/calendar.tsx b/dashboard/src/components/ui/calendar.tsx
index be233fa..c68f6e5 100644
--- a/dashboard/src/components/ui/calendar.tsx
+++ b/dashboard/src/components/ui/calendar.tsx
@@ -2,62 +2,62 @@ import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { buttonVariants } from "@marzneshin/components/ui/button"
export type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- ...props
+ className,
+ classNames,
+ showOutsideDays = true,
+ ...props
}: CalendarProps) {
- return (
- <DayPicker
- showOutsideDays={showOutsideDays}
- className={cn("p-3", className)}
- classNames={{
- months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
- month: "space-y-4",
- caption: "flex justify-center pt-1 relative items-center",
- caption_label: "text-sm font-medium",
- nav: "space-x-1 flex items-center",
- nav_button: cn(
- buttonVariants({ variant: "outline" }),
- "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
- ),
- nav_button_previous: "absolute left-1",
- nav_button_next: "absolute right-1",
- table: "w-full border-collapse space-y-1",
- head_row: "flex",
- head_cell:
- "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
- row: "flex w-full mt-2",
- cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
- day: cn(
- buttonVariants({ variant: "ghost" }),
- "h-9 w-9 p-0 font-normal aria-selected:opacity-100"
- ),
- day_range_end: "day-range-end",
- day_selected:
- "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
- day_today: "bg-accent text-accent-foreground",
- day_outside:
- "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
- day_disabled: "text-muted-foreground opacity-50",
- day_range_middle:
- "aria-selected:bg-accent aria-selected:text-accent-foreground",
- day_hidden: "invisible",
- ...classNames,
- }}
- components={{
- IconLeft: ({ ...props }) => <ChevronLeft className="w-4 h-4" {...props} />,
- IconRight: ({ ...props }) => <ChevronRight className="w-4 h-4" {...props} />,
- }}
- {...props}
- />
- )
+ return (
+ <DayPicker
+ showOutsideDays={showOutsideDays}
+ className={cn("p-3", className)}
+ classNames={{
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
+ month: "space-y-4",
+ caption: "flex justify-center pt-1 relative items-center",
+ caption_label: "text-sm font-medium",
+ nav: "space-x-1 flex items-center",
+ nav_button: cn(
+ buttonVariants({ variant: "outline" }),
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
+ ),
+ nav_button_previous: "absolute left-1",
+ nav_button_next: "absolute right-1",
+ table: "w-full border-collapse space-y-1",
+ head_row: "flex",
+ head_cell:
+ "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
+ row: "flex w-full mt-2",
+ cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
+ day: cn(
+ buttonVariants({ variant: "ghost" }),
+ "h-9 w-9 p-0 font-normal aria-selected:opacity-100"
+ ),
+ day_range_end: "day-range-end",
+ day_selected:
+ "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
+ day_today: "bg-accent text-accent-foreground",
+ day_outside:
+ "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
+ day_disabled: "text-muted-foreground opacity-50",
+ day_range_middle:
+ "aria-selected:bg-accent aria-selected:text-accent-foreground",
+ day_hidden: "invisible",
+ ...classNames,
+ }}
+ components={{
+ IconLeft: ({ ...props }) => <ChevronLeft className="w-4 h-4" {...props} />,
+ IconRight: ({ ...props }) => <ChevronRight className="w-4 h-4" {...props} />,
+ }}
+ {...props}
+ />
+ )
}
Calendar.displayName = "Calendar"
diff --git a/dashboard/src/components/ui/card.tsx b/dashboard/src/components/ui/card.tsx
index 9a3731f..6c6c534 100644
--- a/dashboard/src/components/ui/card.tsx
+++ b/dashboard/src/components/ui/card.tsx
@@ -1,78 +1,78 @@
import * as React from "react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Card = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes<HTMLDivElement>
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
- <div
- ref={ref}
- className={cn(
- "rounded-lg border bg-card text-card-foreground shadow-sm",
- className
- )}
- {...props}
- />
+ <div
+ ref={ref}
+ className={cn(
+ "rounded-lg border bg-card text-card-foreground shadow-sm",
+ className
+ )}
+ {...props}
+ />
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes<HTMLDivElement>
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
- <div
- ref={ref}
- className={cn("flex flex-col space-y-1.5 p-6", className)}
- {...props}
- />
+ <div
+ ref={ref}
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
+ {...props}
+ />
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes<HTMLHeadingElement>
+ HTMLParagraphElement,
+ React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
- <h3
- ref={ref}
- className={cn(
- "text-2xl font-semibold leading-none tracking-tight",
- className
- )}
- {...props}
- />
+ <h3
+ ref={ref}
+ className={cn(
+ "text-2xl font-semibold leading-none tracking-tight",
+ className
+ )}
+ {...props}
+ />
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes<HTMLParagraphElement>
+ HTMLParagraphElement,
+ React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
- <p
- ref={ref}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
+ <p
+ ref={ref}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes<HTMLDivElement>
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes<HTMLDivElement>
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
- <div
- ref={ref}
- className={cn("flex items-center p-6 pt-0", className)}
- {...props}
- />
+ <div
+ ref={ref}
+ className={cn("flex items-center p-6 pt-0", className)}
+ {...props}
+ />
))
CardFooter.displayName = "CardFooter"
diff --git a/dashboard/src/components/ui/chart.tsx b/dashboard/src/components/ui/chart.tsx
index 05e3adb..8cf82fa 100644
--- a/dashboard/src/components/ui/chart.tsx
+++ b/dashboard/src/components/ui/chart.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import * as RechartsPrimitive from "recharts"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
// Format: { THEME_NAME: CSS_SELECTOR }
const THEMES = { light: "", dark: ".dark" } as const
diff --git a/dashboard/src/components/ui/checkbox.tsx b/dashboard/src/components/ui/checkbox.tsx
index 863795b..1057bed 100644
--- a/dashboard/src/components/ui/checkbox.tsx
+++ b/dashboard/src/components/ui/checkbox.tsx
@@ -2,26 +2,26 @@ import * as React from "react"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
import { Check } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Checkbox = React.forwardRef<
- React.ElementRef<typeof CheckboxPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
>(({ className, ...props }, ref) => (
- <CheckboxPrimitive.Root
- ref={ref}
- className={cn(
- "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
- className
- )}
- {...props}
- >
- <CheckboxPrimitive.Indicator
- className={cn("flex items-center justify-center text-current")}
+ <CheckboxPrimitive.Root
+ ref={ref}
+ className={cn(
+ "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
+ className
+ )}
+ {...props}
>
- <Check className="h-4 w-4" />
- </CheckboxPrimitive.Indicator>
- </CheckboxPrimitive.Root>
+ <CheckboxPrimitive.Indicator
+ className={cn("flex items-center justify-center text-current")}
+ >
+ <Check className="h-4 w-4" />
+ </CheckboxPrimitive.Indicator>
+ </CheckboxPrimitive.Root>
))
Checkbox.displayName = CheckboxPrimitive.Root.displayName
diff --git a/dashboard/src/components/ui/command.tsx b/dashboard/src/components/ui/command.tsx
index 3152023..96f2586 100644
--- a/dashboard/src/components/ui/command.tsx
+++ b/dashboard/src/components/ui/command.tsx
@@ -3,151 +3,151 @@ import { type DialogProps } from "@radix-ui/react-dialog"
import { Command as CommandPrimitive } from "cmdk"
import { Search } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { Dialog, DialogContent } from "@marzneshin/components/ui/dialog"
const Command = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive>
+ React.ElementRef<typeof CommandPrimitive>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
>(({ className, ...props }, ref) => (
- <CommandPrimitive
- ref={ref}
- className={cn(
- "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
- className
- )}
- {...props}
- />
+ <CommandPrimitive
+ ref={ref}
+ className={cn(
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
+ className
+ )}
+ {...props}
+ />
))
Command.displayName = CommandPrimitive.displayName
-interface CommandDialogProps extends DialogProps {}
+interface CommandDialogProps extends DialogProps { }
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
- return (
- <Dialog {...props}>
- <DialogContent className="overflow-hidden p-0 shadow-lg">
- <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
- {children}
- </Command>
- </DialogContent>
- </Dialog>
- )
+ return (
+ <Dialog {...props}>
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
+ {children}
+ </Command>
+ </DialogContent>
+ </Dialog>
+ )
}
const CommandInput = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.Input>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
+ React.ElementRef<typeof CommandPrimitive.Input>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
- <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
- <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
- <CommandPrimitive.Input
- ref={ref}
- className={cn(
- "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
- className
- )}
- {...props}
- />
- </div>
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
+ <CommandPrimitive.Input
+ ref={ref}
+ className={cn(
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
+ className
+ )}
+ {...props}
+ />
+ </div>
))
CommandInput.displayName = CommandPrimitive.Input.displayName
const CommandList = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.List>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
+ React.ElementRef<typeof CommandPrimitive.List>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
>(({ className, ...props }, ref) => (
- <CommandPrimitive.List
- ref={ref}
- className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
- {...props}
- />
+ <CommandPrimitive.List
+ ref={ref}
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
+ {...props}
+ />
))
CommandList.displayName = CommandPrimitive.List.displayName
const CommandEmpty = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.Empty>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
+ React.ElementRef<typeof CommandPrimitive.Empty>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
>((props, ref) => (
- <CommandPrimitive.Empty
- ref={ref}
- className="py-6 text-center text-sm"
- {...props}
- />
+ <CommandPrimitive.Empty
+ ref={ref}
+ className="py-6 text-center text-sm"
+ {...props}
+ />
))
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
const CommandGroup = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.Group>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
+ React.ElementRef<typeof CommandPrimitive.Group>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
>(({ className, ...props }, ref) => (
- <CommandPrimitive.Group
- ref={ref}
- className={cn(
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
- className
- )}
- {...props}
- />
+ <CommandPrimitive.Group
+ ref={ref}
+ className={cn(
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
+ className
+ )}
+ {...props}
+ />
))
CommandGroup.displayName = CommandPrimitive.Group.displayName
const CommandSeparator = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.Separator>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
+ React.ElementRef<typeof CommandPrimitive.Separator>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
>(({ className, ...props }, ref) => (
- <CommandPrimitive.Separator
- ref={ref}
- className={cn("-mx-1 h-px bg-border", className)}
- {...props}
- />
+ <CommandPrimitive.Separator
+ ref={ref}
+ className={cn("-mx-1 h-px bg-border", className)}
+ {...props}
+ />
))
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
const CommandItem = React.forwardRef<
- React.ElementRef<typeof CommandPrimitive.Item>,
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
+ React.ElementRef<typeof CommandPrimitive.Item>,
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
- <CommandPrimitive.Item
- ref={ref}
- className={cn(
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
- className
- )}
- {...props}
- />
+ <CommandPrimitive.Item
+ ref={ref}
+ className={cn(
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
+ className
+ )}
+ {...props}
+ />
))
CommandItem.displayName = CommandPrimitive.Item.displayName
const CommandShortcut = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLSpanElement>) => {
- return (
- <span
- className={cn(
- "ml-auto text-xs tracking-widest text-muted-foreground",
- className
- )}
- {...props}
- />
- )
+ return (
+ <span
+ className={cn(
+ "ml-auto text-xs tracking-widest text-muted-foreground",
+ className
+ )}
+ {...props}
+ />
+ )
}
CommandShortcut.displayName = "CommandShortcut"
export {
- Command,
- CommandDialog,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
- CommandShortcut,
- CommandSeparator,
+ Command,
+ CommandDialog,
+ CommandInput,
+ CommandList,
+ CommandEmpty,
+ CommandGroup,
+ CommandItem,
+ CommandShortcut,
+ CommandSeparator,
}
diff --git a/dashboard/src/components/ui/dialog.tsx b/dashboard/src/components/ui/dialog.tsx
index 37d5490..3db71c2 100644
--- a/dashboard/src/components/ui/dialog.tsx
+++ b/dashboard/src/components/ui/dialog.tsx
@@ -2,7 +2,7 @@ import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Dialog = DialogPrimitive.Root
@@ -13,108 +13,108 @@ const DialogPortal = DialogPrimitive.Portal
const DialogClose = DialogPrimitive.Close
const DialogOverlay = React.forwardRef<
- React.ElementRef<typeof DialogPrimitive.Overlay>,
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
- <DialogPrimitive.Overlay
- ref={ref}
- className={cn(
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
- className
- )}
- {...props}
- />
+ <DialogPrimitive.Overlay
+ ref={ref}
+ className={cn(
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
+ className
+ )}
+ {...props}
+ />
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef<
- React.ElementRef<typeof DialogPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
+ React.ElementRef<typeof DialogPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
- <DialogPortal>
- <DialogOverlay />
- <DialogPrimitive.Content
- ref={ref}
- className={cn(
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
- className
- )}
- {...props}
- >
- {children}
- <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
- <X className="h-4 w-4" />
- <span className="sr-only">Close</span>
- </DialogPrimitive.Close>
- </DialogPrimitive.Content>
- </DialogPortal>
+ <DialogPortal>
+ <DialogOverlay />
+ <DialogPrimitive.Content
+ ref={ref}
+ className={cn(
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
+ className
+ )}
+ {...props}
+ >
+ {children}
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
+ <X className="h-4 w-4" />
+ <span className="sr-only">Close</span>
+ </DialogPrimitive.Close>
+ </DialogPrimitive.Content>
+ </DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName
const DialogHeader = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col space-y-1.5 text-center sm:text-left",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col space-y-1.5 text-center sm:text-left",
+ className
+ )}
+ {...props}
+ />
)
DialogHeader.displayName = "DialogHeader"
const DialogFooter = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
+ className
+ )}
+ {...props}
+ />
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef<
- React.ElementRef<typeof DialogPrimitive.Title>,
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
+ React.ElementRef<typeof DialogPrimitive.Title>,
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
- <DialogPrimitive.Title
- ref={ref}
- className={cn(
- "text-lg font-semibold leading-none tracking-tight",
- className
- )}
- {...props}
- />
+ <DialogPrimitive.Title
+ ref={ref}
+ className={cn(
+ "text-lg font-semibold leading-none tracking-tight",
+ className
+ )}
+ {...props}
+ />
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef<
- React.ElementRef<typeof DialogPrimitive.Description>,
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
+ React.ElementRef<typeof DialogPrimitive.Description>,
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
- <DialogPrimitive.Description
- ref={ref}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
+ <DialogPrimitive.Description
+ ref={ref}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
- Dialog,
- DialogPortal,
- DialogOverlay,
- DialogClose,
- DialogTrigger,
- DialogContent,
- DialogHeader,
- DialogFooter,
- DialogTitle,
- DialogDescription,
+ Dialog,
+ DialogPortal,
+ DialogOverlay,
+ DialogClose,
+ DialogTrigger,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
}
diff --git a/dashboard/src/components/ui/drawer.tsx b/dashboard/src/components/ui/drawer.tsx
index 7484336..c0fa557 100644
--- a/dashboard/src/components/ui/drawer.tsx
+++ b/dashboard/src/components/ui/drawer.tsx
@@ -1,16 +1,16 @@
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Drawer = ({
- shouldScaleBackground = true,
- ...props
+ shouldScaleBackground = true,
+ ...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
- <DrawerPrimitive.Root
- shouldScaleBackground={shouldScaleBackground}
- {...props}
- />
+ <DrawerPrimitive.Root
+ shouldScaleBackground={shouldScaleBackground}
+ {...props}
+ />
)
Drawer.displayName = "Drawer"
@@ -21,96 +21,96 @@ const DrawerPortal = DrawerPrimitive.Portal
const DrawerClose = DrawerPrimitive.Close
const DrawerOverlay = React.forwardRef<
- React.ElementRef<typeof DrawerPrimitive.Overlay>,
- React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
+ React.ElementRef<typeof DrawerPrimitive.Overlay>,
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
>(({ className, ...props }, ref) => (
- <DrawerPrimitive.Overlay
- ref={ref}
- className={cn("fixed inset-0 z-50 bg-black/80", className)}
- {...props}
- />
+ <DrawerPrimitive.Overlay
+ ref={ref}
+ className={cn("fixed inset-0 z-50 bg-black/80", className)}
+ {...props}
+ />
))
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
const DrawerContent = React.forwardRef<
- React.ElementRef<typeof DrawerPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
+ React.ElementRef<typeof DrawerPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
>(({ className, children, ...props }, ref) => (
- <DrawerPortal>
- <DrawerOverlay />
- <DrawerPrimitive.Content
- ref={ref}
- className={cn(
- "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
- className
- )}
- {...props}
- >
- <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
- {children}
- </DrawerPrimitive.Content>
- </DrawerPortal>
+ <DrawerPortal>
+ <DrawerOverlay />
+ <DrawerPrimitive.Content
+ ref={ref}
+ className={cn(
+ "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
+ className
+ )}
+ {...props}
+ >
+ <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
+ {children}
+ </DrawerPrimitive.Content>
+ </DrawerPortal>
))
DrawerContent.displayName = "DrawerContent"
const DrawerHeader = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
- {...props}
- />
+ <div
+ className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
+ {...props}
+ />
)
DrawerHeader.displayName = "DrawerHeader"
const DrawerFooter = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn("mt-auto flex flex-col gap-2 p-4", className)}
- {...props}
- />
+ <div
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
+ {...props}
+ />
)
DrawerFooter.displayName = "DrawerFooter"
const DrawerTitle = React.forwardRef<
- React.ElementRef<typeof DrawerPrimitive.Title>,
- React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
+ React.ElementRef<typeof DrawerPrimitive.Title>,
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
>(({ className, ...props }, ref) => (
- <DrawerPrimitive.Title
- ref={ref}
- className={cn(
- "text-lg font-semibold leading-none tracking-tight",
- className
- )}
- {...props}
- />
+ <DrawerPrimitive.Title
+ ref={ref}
+ className={cn(
+ "text-lg font-semibold leading-none tracking-tight",
+ className
+ )}
+ {...props}
+ />
))
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
const DrawerDescription = React.forwardRef<
- React.ElementRef<typeof DrawerPrimitive.Description>,
- React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
+ React.ElementRef<typeof DrawerPrimitive.Description>,
+ React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
>(({ className, ...props }, ref) => (
- <DrawerPrimitive.Description
- ref={ref}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
+ <DrawerPrimitive.Description
+ ref={ref}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
export {
- Drawer,
- DrawerPortal,
- DrawerOverlay,
- DrawerTrigger,
- DrawerClose,
- DrawerContent,
- DrawerHeader,
- DrawerFooter,
- DrawerTitle,
- DrawerDescription,
+ Drawer,
+ DrawerPortal,
+ DrawerOverlay,
+ DrawerTrigger,
+ DrawerClose,
+ DrawerContent,
+ DrawerHeader,
+ DrawerFooter,
+ DrawerTitle,
+ DrawerDescription,
}
diff --git a/dashboard/src/components/ui/dropdown-menu.tsx b/dashboard/src/components/ui/dropdown-menu.tsx
index 000f13c..099a032 100644
--- a/dashboard/src/components/ui/dropdown-menu.tsx
+++ b/dashboard/src/components/ui/dropdown-menu.tsx
@@ -2,7 +2,7 @@ import * as React from "react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
import { Check, ChevronLeft, ChevronRight, Circle } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const DropdownMenu = DropdownMenuPrimitive.Root
diff --git a/dashboard/src/components/ui/form.tsx b/dashboard/src/components/ui/form.tsx
index 7d7d3ff..1b6760b 100644
--- a/dashboard/src/components/ui/form.tsx
+++ b/dashboard/src/components/ui/form.tsx
@@ -2,175 +2,175 @@ import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { Slot } from "@radix-ui/react-slot"
import {
- Controller,
- ControllerProps,
- FieldPath,
- FieldValues,
- FormProvider,
- useFormContext,
+ Controller,
+ ControllerProps,
+ FieldPath,
+ FieldValues,
+ FormProvider,
+ useFormContext,
} from "react-hook-form"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { Label } from "@marzneshin/components/ui/label"
const Form = FormProvider
type FormFieldContextValue<
- TFieldValues extends FieldValues = FieldValues,
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
+ TFieldValues extends FieldValues = FieldValues,
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
- name: TName
+ name: TName
}
const FormFieldContext = React.createContext<FormFieldContextValue>(
- {} as FormFieldContextValue
+ {} as FormFieldContextValue
)
const FormField = <
- TFieldValues extends FieldValues = FieldValues,
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
+ TFieldValues extends FieldValues = FieldValues,
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
- ...props
+ ...props
}: ControllerProps<TFieldValues, TName>) => {
- return (
- <FormFieldContext.Provider value={{ name: props.name }}>
- <Controller {...props} />
- </FormFieldContext.Provider>
- )
+ return (
+ <FormFieldContext.Provider value={{ name: props.name }}>
+ <Controller {...props} />
+ </FormFieldContext.Provider>
+ )
}
const useFormField = () => {
- const fieldContext = React.useContext(FormFieldContext)
- const itemContext = React.useContext(FormItemContext)
- const { getFieldState, formState } = useFormContext()
-
- const fieldState = getFieldState(fieldContext.name, formState)
-
- if (!fieldContext) {
- throw new Error("useFormField should be used within <FormField>")
- }
-
- const { id } = itemContext
-
- return {
- id,
- name: fieldContext.name,
- formItemId: `${id}-form-item`,
- formDescriptionId: `${id}-form-item-description`,
- formMessageId: `${id}-form-item-message`,
- ...fieldState,
- }
+ const fieldContext = React.useContext(FormFieldContext)
+ const itemContext = React.useContext(FormItemContext)
+ const { getFieldState, formState } = useFormContext()
+
+ const fieldState = getFieldState(fieldContext.name, formState)
+
+ if (!fieldContext) {
+ throw new Error("useFormField should be used within <FormField>")
+ }
+
+ const { id } = itemContext
+
+ return {
+ id,
+ name: fieldContext.name,
+ formItemId: `${id}-form-item`,
+ formDescriptionId: `${id}-form-item-description`,
+ formMessageId: `${id}-form-item-message`,
+ ...fieldState,
+ }
}
type FormItemContextValue = {
- id: string
+ id: string
}
const FormItemContext = React.createContext<FormItemContextValue>(
- {} as FormItemContextValue
+ {} as FormItemContextValue
)
const FormItem = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes<HTMLDivElement>
+ HTMLDivElement,
+ React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
- const id = React.useId()
+ const id = React.useId()
- return (
- <FormItemContext.Provider value={{ id }}>
- <div ref={ref} className={cn("space-y-2", className)} {...props} />
- </FormItemContext.Provider>
- )
+ return (
+ <FormItemContext.Provider value={{ id }}>
+ <div ref={ref} className={cn("space-y-2", className)} {...props} />
+ </FormItemContext.Provider>
+ )
})
FormItem.displayName = "FormItem"
const FormLabel = React.forwardRef<
- React.ElementRef<typeof LabelPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
+ React.ElementRef<typeof LabelPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
- const { error, formItemId } = useFormField()
-
- return (
- <Label
- ref={ref}
- className={cn(error && "text-destructive", "font-semibold", className)}
- htmlFor={formItemId}
- {...props}
- />
- )
+ const { error, formItemId } = useFormField()
+
+ return (
+ <Label
+ ref={ref}
+ className={cn(error && "text-destructive", "font-semibold", className)}
+ htmlFor={formItemId}
+ {...props}
+ />
+ )
})
FormLabel.displayName = "FormLabel"
const FormControl = React.forwardRef<
- React.ElementRef<typeof Slot>,
- React.ComponentPropsWithoutRef<typeof Slot>
+ React.ElementRef<typeof Slot>,
+ React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
-
- return (
- <Slot
- ref={ref}
- id={formItemId}
- aria-describedby={
- !error
- ? `${formDescriptionId}`
- : `${formDescriptionId} ${formMessageId}`
- }
- aria-invalid={!!error}
- {...props}
- />
- )
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
+
+ return (
+ <Slot
+ ref={ref}
+ id={formItemId}
+ aria-describedby={
+ !error
+ ? `${formDescriptionId}`
+ : `${formDescriptionId} ${formMessageId}`
+ }
+ aria-invalid={!!error}
+ {...props}
+ />
+ )
})
FormControl.displayName = "FormControl"
const FormDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes<HTMLParagraphElement>
+ HTMLParagraphElement,
+ React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
- const { formDescriptionId } = useFormField()
-
- return (
- <p
- ref={ref}
- id={formDescriptionId}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
- )
+ const { formDescriptionId } = useFormField()
+
+ return (
+ <p
+ ref={ref}
+ id={formDescriptionId}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
+ )
})
FormDescription.displayName = "FormDescription"
const FormMessage = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes<HTMLParagraphElement>
+ HTMLParagraphElement,
+ React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
- const { error, formMessageId } = useFormField()
- const body = error ? String(error?.message) : children
-
- if (!body) {
- return null
- }
-
- return (
- <p
- ref={ref}
- id={formMessageId}
- className={cn("text-sm font-medium text-destructive", className)}
- {...props}
- >
- {body}
- </p>
- )
+ const { error, formMessageId } = useFormField()
+ const body = error ? String(error?.message) : children
+
+ if (!body) {
+ return null
+ }
+
+ return (
+ <p
+ ref={ref}
+ id={formMessageId}
+ className={cn("text-sm font-medium text-destructive", className)}
+ {...props}
+ >
+ {body}
+ </p>
+ )
})
FormMessage.displayName = "FormMessage"
export {
- useFormField,
- Form,
- FormItem,
- FormLabel,
- FormControl,
- FormDescription,
- FormMessage,
- FormField,
+ useFormField,
+ Form,
+ FormItem,
+ FormLabel,
+ FormControl,
+ FormDescription,
+ FormMessage,
+ FormField,
}
diff --git a/dashboard/src/components/ui/input.tsx b/dashboard/src/components/ui/input.tsx
index e256fc5..b86af48 100644
--- a/dashboard/src/components/ui/input.tsx
+++ b/dashboard/src/components/ui/input.tsx
@@ -1,24 +1,24 @@
import * as React from "react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
export interface InputProps
- extends React.InputHTMLAttributes<HTMLInputElement> {}
+ extends React.InputHTMLAttributes<HTMLInputElement> { }
const Input = React.forwardRef<HTMLInputElement, InputProps>(
- ({ className, type, ...props }, ref) => {
- return (
- <input
- type={type}
- className={cn(
- "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
- className
- )}
- ref={ref}
- {...props}
- />
- )
- }
+ ({ className, type, ...props }, ref) => {
+ return (
+ <input
+ type={type}
+ className={cn(
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
+ className
+ )}
+ ref={ref}
+ {...props}
+ />
+ )
+ }
)
Input.displayName = "Input"
diff --git a/dashboard/src/components/ui/label.tsx b/dashboard/src/components/ui/label.tsx
index d6cb28b..f65c22e 100644
--- a/dashboard/src/components/ui/label.tsx
+++ b/dashboard/src/components/ui/label.tsx
@@ -2,22 +2,22 @@ import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const labelVariants = cva(
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
+ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
- React.ElementRef<typeof LabelPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
+ React.ElementRef<typeof LabelPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
- <LabelPrimitive.Root
- ref={ref}
- className={cn(labelVariants(), className)}
- {...props}
- />
+ <LabelPrimitive.Root
+ ref={ref}
+ className={cn(labelVariants(), className)}
+ {...props}
+ />
))
Label.displayName = LabelPrimitive.Root.displayName
diff --git a/dashboard/src/components/ui/popover.tsx b/dashboard/src/components/ui/popover.tsx
index eba69cf..64c42bb 100644
--- a/dashboard/src/components/ui/popover.tsx
+++ b/dashboard/src/components/ui/popover.tsx
@@ -1,28 +1,28 @@
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Popover = PopoverPrimitive.Root
const PopoverTrigger = PopoverPrimitive.Trigger
const PopoverContent = React.forwardRef<
- React.ElementRef<typeof PopoverPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
+ React.ElementRef<typeof PopoverPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
- <PopoverPrimitive.Portal>
- <PopoverPrimitive.Content
- ref={ref}
- align={align}
- sideOffset={sideOffset}
- className={cn(
- "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
- className
- )}
- {...props}
- />
- </PopoverPrimitive.Portal>
+ <PopoverPrimitive.Portal>
+ <PopoverPrimitive.Content
+ ref={ref}
+ align={align}
+ sideOffset={sideOffset}
+ className={cn(
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
+ className
+ )}
+ {...props}
+ />
+ </PopoverPrimitive.Portal>
))
PopoverContent.displayName = PopoverPrimitive.Content.displayName
diff --git a/dashboard/src/components/ui/progress.tsx b/dashboard/src/components/ui/progress.tsx
index f03d0a2..0dfd4ad 100644
--- a/dashboard/src/components/ui/progress.tsx
+++ b/dashboard/src/components/ui/progress.tsx
@@ -1,25 +1,25 @@
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Progress = React.forwardRef<
- React.ElementRef<typeof ProgressPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
+ React.ElementRef<typeof ProgressPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
- <ProgressPrimitive.Root
- ref={ref}
- className={cn(
- "relative h-4 w-full overflow-hidden rounded-full bg-secondary",
- className
- )}
- {...props}
- >
- <ProgressPrimitive.Indicator
- className="h-full w-full flex-1 bg-primary transition-all"
- style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
- />
- </ProgressPrimitive.Root>
+ <ProgressPrimitive.Root
+ ref={ref}
+ className={cn(
+ "relative h-4 w-full overflow-hidden rounded-full bg-secondary",
+ className
+ )}
+ {...props}
+ >
+ <ProgressPrimitive.Indicator
+ className="h-full w-full flex-1 bg-primary transition-all"
+ style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
+ />
+ </ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName
diff --git a/dashboard/src/components/ui/radio-group.tsx b/dashboard/src/components/ui/radio-group.tsx
index 5b63af3..f04b672 100644
--- a/dashboard/src/components/ui/radio-group.tsx
+++ b/dashboard/src/components/ui/radio-group.tsx
@@ -2,40 +2,40 @@ import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const RadioGroup = React.forwardRef<
- React.ElementRef<typeof RadioGroupPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
+ React.ElementRef<typeof RadioGroupPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
>(({ className, ...props }, ref) => {
- return (
- <RadioGroupPrimitive.Root
- className={cn("grid gap-2", className)}
- {...props}
- ref={ref}
- />
- )
+ return (
+ <RadioGroupPrimitive.Root
+ className={cn("grid gap-2", className)}
+ {...props}
+ ref={ref}
+ />
+ )
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
const RadioGroupItem = React.forwardRef<
- React.ElementRef<typeof RadioGroupPrimitive.Item>,
- React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
+ React.ElementRef<typeof RadioGroupPrimitive.Item>,
+ React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
>(({ className, ...props }, ref) => {
- return (
- <RadioGroupPrimitive.Item
- ref={ref}
- className={cn(
- "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
- className
- )}
- {...props}
- >
- <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
- <Circle className="h-2.5 w-2.5 fill-current text-current" />
- </RadioGroupPrimitive.Indicator>
- </RadioGroupPrimitive.Item>
- )
+ return (
+ <RadioGroupPrimitive.Item
+ ref={ref}
+ className={cn(
+ "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
+ className
+ )}
+ {...props}
+ >
+ <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
+ <Circle className="h-2.5 w-2.5 fill-current text-current" />
+ </RadioGroupPrimitive.Indicator>
+ </RadioGroupPrimitive.Item>
+ )
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
diff --git a/dashboard/src/components/ui/resizable.tsx b/dashboard/src/components/ui/resizable.tsx
index dc053ca..c1bbc85 100644
--- a/dashboard/src/components/ui/resizable.tsx
+++ b/dashboard/src/components/ui/resizable.tsx
@@ -1,43 +1,43 @@
import { GripVertical } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const ResizablePanelGroup = ({
- className,
- ...props
+ className,
+ ...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
- <ResizablePrimitive.PanelGroup
- className={cn(
- "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
- className
- )}
- {...props}
- />
+ <ResizablePrimitive.PanelGroup
+ className={cn(
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
+ className
+ )}
+ {...props}
+ />
)
const ResizablePanel = ResizablePrimitive.Panel
const ResizableHandle = ({
- withHandle,
- className,
- ...props
+ withHandle,
+ className,
+ ...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
- withHandle?: boolean
+ withHandle?: boolean
}) => (
- <ResizablePrimitive.PanelResizeHandle
- className={cn(
- "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
- className
- )}
- {...props}
- >
- {withHandle && (
- <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
- <GripVertical className="h-2.5 w-2.5" />
- </div>
- )}
- </ResizablePrimitive.PanelResizeHandle>
+ <ResizablePrimitive.PanelResizeHandle
+ className={cn(
+ "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
+ className
+ )}
+ {...props}
+ >
+ {withHandle && (
+ <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
+ <GripVertical className="h-2.5 w-2.5" />
+ </div>
+ )}
+ </ResizablePrimitive.PanelResizeHandle>
)
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
diff --git a/dashboard/src/components/ui/scroll-area.tsx b/dashboard/src/components/ui/scroll-area.tsx
index f309f1c..4d66349 100644
--- a/dashboard/src/components/ui/scroll-area.tsx
+++ b/dashboard/src/components/ui/scroll-area.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
@@ -31,9 +31,9 @@ const ScrollBar = React.forwardRef<
className={cn(
"flex touch-none select-none transition-colors",
orientation === "vertical" &&
- "h-full w-2.5 border-l border-l-transparent p-[1px]",
+ "h-full w-2.5 border-l border-l-transparent p-[1px]",
orientation === "horizontal" &&
- "h-2.5 flex-col border-t border-t-transparent p-[1px]",
+ "h-2.5 flex-col border-t border-t-transparent p-[1px]",
className
)}
{...props}
diff --git a/dashboard/src/components/ui/select.tsx b/dashboard/src/components/ui/select.tsx
index d06ddc4..1ae4f87 100644
--- a/dashboard/src/components/ui/select.tsx
+++ b/dashboard/src/components/ui/select.tsx
@@ -2,7 +2,7 @@ import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { Check, ChevronDown, ChevronUp } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Select = SelectPrimitive.Root
@@ -11,148 +11,148 @@ const SelectGroup = SelectPrimitive.Group
const SelectValue = SelectPrimitive.Value
const SelectTrigger = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.Trigger>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
- <SelectPrimitive.Trigger
- ref={ref}
- className={cn(
- "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
- className
- )}
- {...props}
- >
- {children}
- <SelectPrimitive.Icon asChild>
- <ChevronDown className="h-4 w-4 opacity-50" />
- </SelectPrimitive.Icon>
- </SelectPrimitive.Trigger>
+ <SelectPrimitive.Trigger
+ ref={ref}
+ className={cn(
+ "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
+ className
+ )}
+ {...props}
+ >
+ {children}
+ <SelectPrimitive.Icon asChild>
+ <ChevronDown className="h-4 w-4 opacity-50" />
+ </SelectPrimitive.Icon>
+ </SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
const SelectScrollUpButton = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
- <SelectPrimitive.ScrollUpButton
- ref={ref}
- className={cn(
- "flex cursor-default items-center justify-center py-1",
- className
- )}
- {...props}
- >
- <ChevronUp className="h-4 w-4" />
- </SelectPrimitive.ScrollUpButton>
+ <SelectPrimitive.ScrollUpButton
+ ref={ref}
+ className={cn(
+ "flex cursor-default items-center justify-center py-1",
+ className
+ )}
+ {...props}
+ >
+ <ChevronUp className="h-4 w-4" />
+ </SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
const SelectScrollDownButton = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
- <SelectPrimitive.ScrollDownButton
- ref={ref}
- className={cn(
- "flex cursor-default items-center justify-center py-1",
- className
- )}
- {...props}
- >
- <ChevronDown className="h-4 w-4" />
- </SelectPrimitive.ScrollDownButton>
+ <SelectPrimitive.ScrollDownButton
+ ref={ref}
+ className={cn(
+ "flex cursor-default items-center justify-center py-1",
+ className
+ )}
+ {...props}
+ >
+ <ChevronDown className="h-4 w-4" />
+ </SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
- SelectPrimitive.ScrollDownButton.displayName
+ SelectPrimitive.ScrollDownButton.displayName
const SelectContent = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
+ React.ElementRef<typeof SelectPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
- <SelectPrimitive.Portal>
- <SelectPrimitive.Content
- ref={ref}
- className={cn(
- "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
- position === "popper" &&
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
- className
- )}
- position={position}
- {...props}
- >
- <SelectScrollUpButton />
- <SelectPrimitive.Viewport
- className={cn(
- "p-1",
- position === "popper" &&
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
- )}
- >
- {children}
- </SelectPrimitive.Viewport>
- <SelectScrollDownButton />
- </SelectPrimitive.Content>
- </SelectPrimitive.Portal>
+ <SelectPrimitive.Portal>
+ <SelectPrimitive.Content
+ ref={ref}
+ className={cn(
+ "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
+ position === "popper" &&
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
+ className
+ )}
+ position={position}
+ {...props}
+ >
+ <SelectScrollUpButton />
+ <SelectPrimitive.Viewport
+ className={cn(
+ "p-1",
+ position === "popper" &&
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
+ )}
+ >
+ {children}
+ </SelectPrimitive.Viewport>
+ <SelectScrollDownButton />
+ </SelectPrimitive.Content>
+ </SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName
const SelectLabel = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.Label>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
+ React.ElementRef<typeof SelectPrimitive.Label>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
- <SelectPrimitive.Label
- ref={ref}
- className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
- {...props}
- />
+ <SelectPrimitive.Label
+ ref={ref}
+ className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
+ {...props}
+ />
))
SelectLabel.displayName = SelectPrimitive.Label.displayName
const SelectItem = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.Item>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
+ React.ElementRef<typeof SelectPrimitive.Item>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
- <SelectPrimitive.Item
- ref={ref}
- className={cn(
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
- className
- )}
- {...props}
- >
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
- <SelectPrimitive.ItemIndicator>
- <Check className="h-4 w-4" />
- </SelectPrimitive.ItemIndicator>
- </span>
+ <SelectPrimitive.Item
+ ref={ref}
+ className={cn(
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+ className
+ )}
+ {...props}
+ >
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
+ <SelectPrimitive.ItemIndicator>
+ <Check className="h-4 w-4" />
+ </SelectPrimitive.ItemIndicator>
+ </span>
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
- </SelectPrimitive.Item>
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
+ </SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName
const SelectSeparator = React.forwardRef<
- React.ElementRef<typeof SelectPrimitive.Separator>,
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
+ React.ElementRef<typeof SelectPrimitive.Separator>,
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
- <SelectPrimitive.Separator
- ref={ref}
- className={cn("-mx-1 my-1 h-px bg-muted", className)}
- {...props}
- />
+ <SelectPrimitive.Separator
+ ref={ref}
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
+ {...props}
+ />
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
export {
- Select,
- SelectGroup,
- SelectValue,
- SelectTrigger,
- SelectContent,
- SelectLabel,
- SelectItem,
- SelectSeparator,
- SelectScrollUpButton,
- SelectScrollDownButton,
+ Select,
+ SelectGroup,
+ SelectValue,
+ SelectTrigger,
+ SelectContent,
+ SelectLabel,
+ SelectItem,
+ SelectSeparator,
+ SelectScrollUpButton,
+ SelectScrollDownButton,
}
diff --git a/dashboard/src/components/ui/separator.tsx b/dashboard/src/components/ui/separator.tsx
index f1078ae..9ecb507 100644
--- a/dashboard/src/components/ui/separator.tsx
+++ b/dashboard/src/components/ui/separator.tsx
@@ -1,28 +1,28 @@
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Separator = React.forwardRef<
- React.ElementRef<typeof SeparatorPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
+ React.ElementRef<typeof SeparatorPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(
- (
- { className, orientation = "horizontal", decorative = true, ...props },
- ref
- ) => (
- <SeparatorPrimitive.Root
- ref={ref}
- decorative={decorative}
- orientation={orientation}
- className={cn(
- "shrink-0 bg-border",
- orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
- className
- )}
- {...props}
- />
- )
+ (
+ { className, orientation = "horizontal", decorative = true, ...props },
+ ref
+ ) => (
+ <SeparatorPrimitive.Root
+ ref={ref}
+ decorative={decorative}
+ orientation={orientation}
+ className={cn(
+ "shrink-0 bg-border",
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
+ className
+ )}
+ {...props}
+ />
+ )
)
Separator.displayName = SeparatorPrimitive.Root.displayName
diff --git a/dashboard/src/components/ui/sheet.tsx b/dashboard/src/components/ui/sheet.tsx
index 1d6a813..51e22e4 100644
--- a/dashboard/src/components/ui/sheet.tsx
+++ b/dashboard/src/components/ui/sheet.tsx
@@ -3,7 +3,7 @@ import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Sheet = SheetPrimitive.Root
@@ -14,125 +14,125 @@ const SheetClose = SheetPrimitive.Close
const SheetPortal = SheetPrimitive.Portal
const SheetOverlay = React.forwardRef<
- React.ElementRef<typeof SheetPrimitive.Overlay>,
- React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
+ React.ElementRef<typeof SheetPrimitive.Overlay>,
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
- <SheetPrimitive.Overlay
- className={cn(
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
- className
- )}
- {...props}
- ref={ref}
- />
+ <SheetPrimitive.Overlay
+ className={cn(
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
+ className
+ )}
+ {...props}
+ ref={ref}
+ />
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
- "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
- {
- variants: {
- side: {
- top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
- bottom:
- "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
- left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
- right:
- "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
- },
- },
- defaultVariants: {
- side: "right",
- },
- }
+ "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
+ {
+ variants: {
+ side: {
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
+ bottom:
+ "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
+ right:
+ "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
+ },
+ },
+ defaultVariants: {
+ side: "right",
+ },
+ }
)
interface SheetContentProps
- extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
- VariantProps<typeof sheetVariants> {}
+ extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
+ VariantProps<typeof sheetVariants> { }
const SheetContent = React.forwardRef<
- React.ElementRef<typeof SheetPrimitive.Content>,
- SheetContentProps
+ React.ElementRef<typeof SheetPrimitive.Content>,
+ SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
- <SheetPortal>
- <SheetOverlay />
- <SheetPrimitive.Content
- ref={ref}
- className={cn(sheetVariants({ side }), className)}
- {...props}
- >
- {children}
- <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
- <X className="h-4 w-4" />
- <span className="sr-only">Close</span>
- </SheetPrimitive.Close>
- </SheetPrimitive.Content>
- </SheetPortal>
+ <SheetPortal>
+ <SheetOverlay />
+ <SheetPrimitive.Content
+ ref={ref}
+ className={cn(sheetVariants({ side }), className)}
+ {...props}
+ >
+ {children}
+ <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
+ <X className="h-4 w-4" />
+ <span className="sr-only">Close</span>
+ </SheetPrimitive.Close>
+ </SheetPrimitive.Content>
+ </SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col space-y-2 text-center sm:text-left",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col space-y-2 text-center sm:text-left",
+ className
+ )}
+ {...props}
+ />
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
- <div
- className={cn(
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
- className
- )}
- {...props}
- />
+ <div
+ className={cn(
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
+ className
+ )}
+ {...props}
+ />
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
- React.ElementRef<typeof SheetPrimitive.Title>,
- React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
+ React.ElementRef<typeof SheetPrimitive.Title>,
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
- <SheetPrimitive.Title
- ref={ref}
- className={cn("text-lg font-semibold text-foreground", className)}
- {...props}
- />
+ <SheetPrimitive.Title
+ ref={ref}
+ className={cn("text-lg font-semibold text-foreground", className)}
+ {...props}
+ />
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
- React.ElementRef<typeof SheetPrimitive.Description>,
- React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
+ React.ElementRef<typeof SheetPrimitive.Description>,
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
- <SheetPrimitive.Description
- ref={ref}
- className={cn("text-sm text-muted-foreground", className)}
- {...props}
- />
+ <SheetPrimitive.Description
+ ref={ref}
+ className={cn("text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
- Sheet,
- SheetPortal,
- SheetOverlay,
- SheetTrigger,
- SheetClose,
- SheetContent,
- SheetHeader,
- SheetFooter,
- SheetTitle,
- SheetDescription,
+ Sheet,
+ SheetPortal,
+ SheetOverlay,
+ SheetTrigger,
+ SheetClose,
+ SheetContent,
+ SheetHeader,
+ SheetFooter,
+ SheetTitle,
+ SheetDescription,
}
diff --git a/dashboard/src/components/ui/skeleton.tsx b/dashboard/src/components/ui/skeleton.tsx
index 72f91f5..470026d 100644
--- a/dashboard/src/components/ui/skeleton.tsx
+++ b/dashboard/src/components/ui/skeleton.tsx
@@ -1,15 +1,15 @@
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
function Skeleton({
- className,
- ...props
+ className,
+ ...props
}: React.HTMLAttributes<HTMLDivElement>) {
- return (
- <div
- className={cn("animate-pulse rounded-md bg-muted", className)}
- {...props}
- />
- )
+ return (
+ <div
+ className={cn("animate-pulse rounded-md bg-muted", className)}
+ {...props}
+ />
+ )
}
export { Skeleton }
diff --git a/dashboard/src/components/ui/sortable/drag-handle.tsx b/dashboard/src/components/ui/sortable/drag-handle.tsx
index 1b9e15b..86a88c0 100644
--- a/dashboard/src/components/ui/sortable/drag-handle.tsx
+++ b/dashboard/src/components/ui/sortable/drag-handle.tsx
@@ -1,7 +1,7 @@
import React from "react";
import { Button, type ButtonProps } from "@marzneshin/components"
import { useSortableItem } from "./use-sortable-item";
-import { composeRefs, cn } from "@marzneshin/utils";
+import { composeRefs, cn } from "@marzneshin/common/utils";
interface SortableDragHandleProps extends ButtonProps {
withHandle?: boolean
diff --git a/dashboard/src/components/ui/sortable/item.tsx b/dashboard/src/components/ui/sortable/item.tsx
index 807f2aa..ed18207 100644
--- a/dashboard/src/components/ui/sortable/item.tsx
+++ b/dashboard/src/components/ui/sortable/item.tsx
@@ -2,7 +2,7 @@ import React from "react"
import { CSS } from "@dnd-kit/utilities"
import { Slot, type SlotProps } from "@radix-ui/react-slot"
import { useSortable } from "@dnd-kit/sortable"
-import { composeRefs, cn } from "@marzneshin/utils"
+import { composeRefs, cn } from "@marzneshin/common/utils"
import type {
UniqueIdentifier,
} from "@dnd-kit/core"
diff --git a/dashboard/src/components/ui/switch.tsx b/dashboard/src/components/ui/switch.tsx
index f7e2613..738c093 100644
--- a/dashboard/src/components/ui/switch.tsx
+++ b/dashboard/src/components/ui/switch.tsx
@@ -1,26 +1,26 @@
import * as React from "react"
import * as SwitchPrimitives from "@radix-ui/react-switch"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Switch = React.forwardRef<
- React.ElementRef<typeof SwitchPrimitives.Root>,
- React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
+ React.ElementRef<typeof SwitchPrimitives.Root>,
+ React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
- <SwitchPrimitives.Root
- className={cn(
- "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
- className
- )}
- {...props}
- ref={ref}
- >
- <SwitchPrimitives.Thumb
- className={cn(
- "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
- )}
- />
- </SwitchPrimitives.Root>
+ <SwitchPrimitives.Root
+ className={cn(
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
+ className
+ )}
+ {...props}
+ ref={ref}
+ >
+ <SwitchPrimitives.Thumb
+ className={cn(
+ "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
+ )}
+ />
+ </SwitchPrimitives.Root>
))
Switch.displayName = SwitchPrimitives.Root.displayName
diff --git a/dashboard/src/components/ui/table.tsx b/dashboard/src/components/ui/table.tsx
index 1ed653d..05b39ba 100644
--- a/dashboard/src/components/ui/table.tsx
+++ b/dashboard/src/components/ui/table.tsx
@@ -1,117 +1,117 @@
import * as React from "react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Table = React.forwardRef<
- HTMLTableElement,
- React.HTMLAttributes<HTMLTableElement>
+ HTMLTableElement,
+ React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
- <div className="relative w-full overflow-auto">
- <table
- ref={ref}
- className={cn("w-full caption-bottom text-sm", className)}
- {...props}
- />
- </div>
+ <div className="relative w-full overflow-auto">
+ <table
+ ref={ref}
+ className={cn("w-full caption-bottom text-sm", className)}
+ {...props}
+ />
+ </div>
))
Table.displayName = "Table"
const TableHeader = React.forwardRef<
- HTMLTableSectionElement,
- React.HTMLAttributes<HTMLTableSectionElement>
+ HTMLTableSectionElement,
+ React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
- <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
+ <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
))
TableHeader.displayName = "TableHeader"
const TableBody = React.forwardRef<
- HTMLTableSectionElement,
- React.HTMLAttributes<HTMLTableSectionElement>
+ HTMLTableSectionElement,
+ React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
- <tbody
- ref={ref}
- className={cn("[&_tr:last-child]:border-0", className)}
- {...props}
- />
+ <tbody
+ ref={ref}
+ className={cn("[&_tr:last-child]:border-0", className)}
+ {...props}
+ />
))
TableBody.displayName = "TableBody"
const TableFooter = React.forwardRef<
- HTMLTableSectionElement,
- React.HTMLAttributes<HTMLTableSectionElement>
+ HTMLTableSectionElement,
+ React.HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
- <tfoot
- ref={ref}
- className={cn(
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
- className
- )}
- {...props}
- />
+ <tfoot
+ ref={ref}
+ className={cn(
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
+ className
+ )}
+ {...props}
+ />
))
TableFooter.displayName = "TableFooter"
const TableRow = React.forwardRef<
- HTMLTableRowElement,
- React.HTMLAttributes<HTMLTableRowElement>
+ HTMLTableRowElement,
+ React.HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
- <tr
- ref={ref}
- className={cn(
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
- className
- )}
- {...props}
- />
+ <tr
+ ref={ref}
+ className={cn(
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
+ className
+ )}
+ {...props}
+ />
))
TableRow.displayName = "TableRow"
const TableHead = React.forwardRef<
- HTMLTableCellElement,
- React.ThHTMLAttributes<HTMLTableCellElement>
+ HTMLTableCellElement,
+ React.ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
- <th
- ref={ref}
- className={cn(
- "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
- className
- )}
- {...props}
- />
+ <th
+ ref={ref}
+ className={cn(
+ "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
+ className
+ )}
+ {...props}
+ />
))
TableHead.displayName = "TableHead"
const TableCell = React.forwardRef<
- HTMLTableCellElement,
- React.TdHTMLAttributes<HTMLTableCellElement>
+ HTMLTableCellElement,
+ React.TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
- <td
- ref={ref}
- className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
- {...props}
- />
+ <td
+ ref={ref}
+ className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
+ {...props}
+ />
))
TableCell.displayName = "TableCell"
const TableCaption = React.forwardRef<
- HTMLTableCaptionElement,
- React.HTMLAttributes<HTMLTableCaptionElement>
+ HTMLTableCaptionElement,
+ React.HTMLAttributes<HTMLTableCaptionElement>
>(({ className, ...props }, ref) => (
- <caption
- ref={ref}
- className={cn("mt-4 text-sm text-muted-foreground", className)}
- {...props}
- />
+ <caption
+ ref={ref}
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
+ {...props}
+ />
))
TableCaption.displayName = "TableCaption"
export {
- Table,
- TableHeader,
- TableBody,
- TableFooter,
- TableHead,
- TableRow,
- TableCell,
- TableCaption,
+ Table,
+ TableHeader,
+ TableBody,
+ TableFooter,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableCaption,
}
diff --git a/dashboard/src/components/ui/tabs.tsx b/dashboard/src/components/ui/tabs.tsx
index a5afbe7..cb73927 100644
--- a/dashboard/src/components/ui/tabs.tsx
+++ b/dashboard/src/components/ui/tabs.tsx
@@ -1,52 +1,52 @@
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const Tabs = TabsPrimitive.Root
const TabsList = React.forwardRef<
- React.ElementRef<typeof TabsPrimitive.List>,
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
+ React.ElementRef<typeof TabsPrimitive.List>,
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
- <TabsPrimitive.List
- ref={ref}
- className={cn(
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
- className
- )}
- {...props}
- />
+ <TabsPrimitive.List
+ ref={ref}
+ className={cn(
+ "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
+ className
+ )}
+ {...props}
+ />
))
TabsList.displayName = TabsPrimitive.List.displayName
const TabsTrigger = React.forwardRef<
- React.ElementRef<typeof TabsPrimitive.Trigger>,
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
+ React.ElementRef<typeof TabsPrimitive.Trigger>,
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
- <TabsPrimitive.Trigger
- ref={ref}
- className={cn(
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
- className
- )}
- {...props}
- />
+ <TabsPrimitive.Trigger
+ ref={ref}
+ className={cn(
+ "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
+ className
+ )}
+ {...props}
+ />
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
const TabsContent = React.forwardRef<
- React.ElementRef<typeof TabsPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
+ React.ElementRef<typeof TabsPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
- <TabsPrimitive.Content
- ref={ref}
- className={cn(
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
- className
- )}
- {...props}
- />
+ <TabsPrimitive.Content
+ ref={ref}
+ className={cn(
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
+ className
+ )}
+ {...props}
+ />
))
TabsContent.displayName = TabsPrimitive.Content.displayName
diff --git a/dashboard/src/components/ui/textarea.tsx b/dashboard/src/components/ui/textarea.tsx
index 8c0de54..37f8f05 100644
--- a/dashboard/src/components/ui/textarea.tsx
+++ b/dashboard/src/components/ui/textarea.tsx
@@ -1,23 +1,23 @@
import * as React from "react"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
export interface TextareaProps
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
+ extends React.TextareaHTMLAttributes<HTMLTextAreaElement> { }
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
- ({ className, ...props }, ref) => {
- return (
- <textarea
- className={cn(
- "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
- className
- )}
- ref={ref}
- {...props}
- />
- )
- }
+ ({ className, ...props }, ref) => {
+ return (
+ <textarea
+ className={cn(
+ "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
+ className
+ )}
+ ref={ref}
+ {...props}
+ />
+ )
+ }
)
Textarea.displayName = "Textarea"
diff --git a/dashboard/src/components/ui/toggle-group.tsx b/dashboard/src/components/ui/toggle-group.tsx
index b33e557..4cafe32 100644
--- a/dashboard/src/components/ui/toggle-group.tsx
+++ b/dashboard/src/components/ui/toggle-group.tsx
@@ -2,56 +2,56 @@ import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { toggleVariants } from "@marzneshin/components/ui/toggle"
const ToggleGroupContext = React.createContext<
- VariantProps<typeof toggleVariants>
+ VariantProps<typeof toggleVariants>
>({
- size: "default",
- variant: "default",
+ size: "default",
+ variant: "default",
})
const ToggleGroup = React.forwardRef<
- React.ElementRef<typeof ToggleGroupPrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
+ React.ElementRef<typeof ToggleGroupPrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
- <ToggleGroupPrimitive.Root
- ref={ref}
- className={cn("flex items-center justify-center gap-1", className)}
- {...props}
- >
- <ToggleGroupContext.Provider value={{ variant, size }}>
- {children}
- </ToggleGroupContext.Provider>
- </ToggleGroupPrimitive.Root>
+ <ToggleGroupPrimitive.Root
+ ref={ref}
+ className={cn("flex items-center justify-center gap-1", className)}
+ {...props}
+ >
+ <ToggleGroupContext.Provider value={{ variant, size }}>
+ {children}
+ </ToggleGroupContext.Provider>
+ </ToggleGroupPrimitive.Root>
))
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
const ToggleGroupItem = React.forwardRef<
- React.ElementRef<typeof ToggleGroupPrimitive.Item>,
- React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
+ React.ElementRef<typeof ToggleGroupPrimitive.Item>,
+ React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
- const context = React.useContext(ToggleGroupContext)
-
- return (
- <ToggleGroupPrimitive.Item
- ref={ref}
- className={cn(
- toggleVariants({
- variant: context.variant || variant,
- size: context.size || size,
- }),
- className
- )}
- {...props}
- >
- {children}
- </ToggleGroupPrimitive.Item>
- )
+ const context = React.useContext(ToggleGroupContext)
+
+ return (
+ <ToggleGroupPrimitive.Item
+ ref={ref}
+ className={cn(
+ toggleVariants({
+ variant: context.variant || variant,
+ size: context.size || size,
+ }),
+ className
+ )}
+ {...props}
+ >
+ {children}
+ </ToggleGroupPrimitive.Item>
+ )
})
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
diff --git a/dashboard/src/components/ui/toggle.tsx b/dashboard/src/components/ui/toggle.tsx
index 71eca7a..f87904e 100644
--- a/dashboard/src/components/ui/toggle.tsx
+++ b/dashboard/src/components/ui/toggle.tsx
@@ -2,40 +2,40 @@ import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const toggleVariants = cva(
- "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
- {
- variants: {
- variant: {
- default: "bg-transparent",
- outline:
- "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
- },
- size: {
- default: "h-10 px-3",
- sm: "h-9 px-2.5",
- lg: "h-11 px-5",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
+ "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
+ {
+ variants: {
+ variant: {
+ default: "bg-transparent",
+ outline:
+ "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
+ },
+ size: {
+ default: "h-10 px-3",
+ sm: "h-9 px-2.5",
+ lg: "h-11 px-5",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
)
const Toggle = React.forwardRef<
- React.ElementRef<typeof TogglePrimitive.Root>,
- React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
+ React.ElementRef<typeof TogglePrimitive.Root>,
+ React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
- <TogglePrimitive.Root
- ref={ref}
- className={cn(toggleVariants({ variant, size, className }))}
- {...props}
- />
+ <TogglePrimitive.Root
+ ref={ref}
+ className={cn(toggleVariants({ variant, size, className }))}
+ {...props}
+ />
))
Toggle.displayName = TogglePrimitive.Root.displayName
diff --git a/dashboard/src/components/ui/tooltip.tsx b/dashboard/src/components/ui/tooltip.tsx
index 5f55b85..65ce299 100644
--- a/dashboard/src/components/ui/tooltip.tsx
+++ b/dashboard/src/components/ui/tooltip.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
const TooltipProvider = TooltipPrimitive.Provider
@@ -10,18 +10,18 @@ const Tooltip = TooltipPrimitive.Root
const TooltipTrigger = TooltipPrimitive.Trigger
const TooltipContent = React.forwardRef<
- React.ElementRef<typeof TooltipPrimitive.Content>,
- React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
+ React.ElementRef<typeof TooltipPrimitive.Content>,
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
- <TooltipPrimitive.Content
- ref={ref}
- sideOffset={sideOffset}
- className={cn(
- "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
- className
- )}
- {...props}
- />
+ <TooltipPrimitive.Content
+ ref={ref}
+ sideOffset={sideOffset}
+ className={cn(
+ "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
+ className
+ )}
+ {...props}
+ />
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName
diff --git a/dashboard/src/features/auth/auth.store.ts b/dashboard/src/features/auth/auth.store.ts
index 23edec7..f429eec 100644
--- a/dashboard/src/features/auth/auth.store.ts
+++ b/dashboard/src/features/auth/auth.store.ts
@@ -1,4 +1,4 @@
-import { fetch } from '@marzneshin/utils';
+import { fetch } from '@marzneshin/common/utils';
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
diff --git a/dashboard/src/features/auth/login/form-error.tsx b/dashboard/src/features/auth/login/form-error.tsx
index 154a015..c16d320 100644
--- a/dashboard/src/features/auth/login/form-error.tsx
+++ b/dashboard/src/features/auth/login/form-error.tsx
@@ -1,5 +1,5 @@
import { Alert, AlertDescription, AlertTitle } from "@marzneshin/components"
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
interface FormErrorProps {
className: string;
diff --git a/dashboard/src/features/auth/login/form.tsx b/dashboard/src/features/auth/login/form.tsx
index 8cfb4e8..f9b4c96 100644
--- a/dashboard/src/features/auth/login/form.tsx
+++ b/dashboard/src/features/auth/login/form.tsx
@@ -1,5 +1,5 @@
-import { fetch } from "@marzneshin/utils"
+import { fetch } from "@marzneshin/common/utils"
import { LoginSchema, useAuth } from "@marzneshin/features/auth";
import { useNavigate } from "@tanstack/react-router";
import { useState } from "react";
diff --git a/dashboard/src/features/bottom-menu/index.tsx b/dashboard/src/features/bottom-menu/index.tsx
index 816fd49..4f9b9dc 100644
--- a/dashboard/src/features/bottom-menu/index.tsx
+++ b/dashboard/src/features/bottom-menu/index.tsx
@@ -3,8 +3,8 @@ import i18n from "@marzneshin/features/i18n";
import { Link } from "@tanstack/react-router";
import { FC } from "react";
import { Box, Home, Server, ServerCog, UsersIcon } from 'lucide-react';
-import { useIsCurrentRoute } from "@marzneshin/hooks";
-import { cn } from "@marzneshin/utils";
+import { useIsCurrentRoute } from "@marzneshin/common/hooks";
+import { cn } from "@marzneshin/common/utils";
type BottomMenuItemProps = Omit<SidebarItem, 'isParent' | 'subItem'>
diff --git a/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx b/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx
index 44eebd7..e210e03 100644
--- a/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx
+++ b/dashboard/src/features/entity-table/components/column-header-combo-filter.tsx
@@ -1,7 +1,7 @@
import * as React from "react"
import { type Column } from "@tanstack/react-table";
import { useEntityTableContext } from "../contexts";
-import { useScreenBreakpoint } from "@marzneshin/hooks";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks";
import { useTranslation } from "react-i18next";
import {
Button,
@@ -18,7 +18,7 @@ import {
PopoverContent,
PopoverTrigger,
} from "@marzneshin/components"
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { Filter, FilterX } from "lucide-react";
interface DataTableColumnHeaderFilterOptionProps<TData, TValue>
diff --git a/dashboard/src/features/entity-table/components/column-header.tsx b/dashboard/src/features/entity-table/components/column-header.tsx
index 5f67034..b4fec44 100644
--- a/dashboard/src/features/entity-table/components/column-header.tsx
+++ b/dashboard/src/features/entity-table/components/column-header.tsx
@@ -15,7 +15,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@marzneshin/components"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
interface DataTableColumnHeaderProps<TData, TValue>
extends React.HTMLAttributes<HTMLDivElement> {
diff --git a/dashboard/src/features/entity-table/components/sidebar-entity-card.tsx b/dashboard/src/features/entity-table/components/sidebar-entity-card.tsx
index bc23a6a..877355f 100644
--- a/dashboard/src/features/entity-table/components/sidebar-entity-card.tsx
+++ b/dashboard/src/features/entity-table/components/sidebar-entity-card.tsx
@@ -4,7 +4,7 @@ import {
} from "@marzneshin/components";
import {
cn
-} from "@marzneshin/utils";
+} from "@marzneshin/common/utils";
import { type FC } from 'react'
interface SidebarEntityCardSectionProps<T> {
diff --git a/dashboard/src/features/entity-table/components/sidebar-entity-selection.tsx b/dashboard/src/features/entity-table/components/sidebar-entity-selection.tsx
index a050b44..ab3dbf4 100644
--- a/dashboard/src/features/entity-table/components/sidebar-entity-selection.tsx
+++ b/dashboard/src/features/entity-table/components/sidebar-entity-selection.tsx
@@ -3,8 +3,8 @@ import {
Table, TableHeader, TableRow, TableBody, TableHead,
ScrollArea, Button,
} from "@marzneshin/components";
-import { useScreenBreakpoint } from "@marzneshin/hooks";
-import { cn } from "@marzneshin/utils";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks";
+import { cn } from "@marzneshin/common/utils";
import {
SidebarEntityCard,
} from "@marzneshin/features/entity-table/components";
diff --git a/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts b/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts
index 4f9e3c7..f81957f 100644
--- a/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts
+++ b/dashboard/src/features/entity-table/hooks/use-sidebar-entity-table.ts
@@ -13,7 +13,7 @@ import {
type SidebarQueryKey,
type UseRowSelectionReturn
} from ".";
-import { useScreenBreakpoint } from "@marzneshin/hooks";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks";
import {
type SidebarEntityCardSectionsProps
} from "@marzneshin/features/entity-table/components";
diff --git a/dashboard/src/features/github-repo/github-repo.tsx b/dashboard/src/features/github-repo/github-repo.tsx
index 09caa88..cc3da60 100644
--- a/dashboard/src/features/github-repo/github-repo.tsx
+++ b/dashboard/src/features/github-repo/github-repo.tsx
@@ -10,7 +10,7 @@ import {
GithubIcon,
StarIcon,
} from "lucide-react";
-import { projectInfo } from "@marzneshin/utils";
+import { projectInfo } from "@marzneshin/common/utils";
interface GithubRepoProps {
variant?: "full" | "mini"
diff --git a/dashboard/src/features/github-repo/services/github-repo.query.ts b/dashboard/src/features/github-repo/services/github-repo.query.ts
index 514cf9b..d185f3f 100644
--- a/dashboard/src/features/github-repo/services/github-repo.query.ts
+++ b/dashboard/src/features/github-repo/services/github-repo.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { projectInfo } from "@marzneshin/utils";
+import { projectInfo } from "@marzneshin/common/utils";
import { ofetch } from "ofetch";
/**
diff --git a/dashboard/src/features/hosts/components/index.ts b/dashboard/src/features/hosts/components/index.ts
deleted file mode 100644
index d585ca9..0000000
--- a/dashboard/src/features/hosts/components/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./popover-guide"
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/security.tsx b/dashboard/src/features/hosts/dialogs/mutation/fields/security.tsx
deleted file mode 100644
index 36ea75e..0000000
--- a/dashboard/src/features/hosts/dialogs/mutation/fields/security.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import {
- FormControl,
- FormField,
- FormItem,
- FormLabel,
- FormMessage,
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue,
-} from "@marzneshin/components";
-import { useEffect, useState } from "react";
-import { useFormContext } from "react-hook-form";
-import { useTranslation } from "react-i18next";
-import { AllowInsecureField, AlpnField, FingerprintField, SniField } from ".";
-
-export const SecurityFields = () => {
- const { t } = useTranslation();
- const form = useFormContext();
- const security = form.watch().security;
-
- const [extraSecurity, setExtraSecurity] = useState<boolean>(
- ["tls", "inbound_default"].includes(security),
- );
- useEffect(() => {
- setExtraSecurity(["tls", "inbound_default"].includes(security));
- }, [security, setExtraSecurity]);
- return (
- <>
- <FormField
- control={form.control}
- name="security"
- render={({ field }) => (
- <FormItem>
- <FormLabel>{t("security")}</FormLabel>
- <Select onValueChange={field.onChange} defaultValue={field.value}>
- <FormControl>
- <SelectTrigger>
- <SelectValue placeholder="Select a verified email to display" />
- </SelectTrigger>
- </FormControl>
- <SelectContent>
- <SelectItem value="none">None</SelectItem>
- <SelectItem value="tls">TLS</SelectItem>
- <SelectItem value="inbound_default">Inbound Default</SelectItem>
- </SelectContent>
- </Select>
- <FormMessage />
- </FormItem>
- )}
- />
- {extraSecurity && (
- <>
- <SniField />
- <div className="flex flex-row w-full gap-2">
- <AlpnField />
- <FingerprintField />
- </div>
- <AllowInsecureField />
- </>
- )}
- </>
- );
-};
diff --git a/dashboard/src/features/hosts/dialogs/settings/index.tsx b/dashboard/src/features/hosts/dialogs/settings/index.tsx
deleted file mode 100644
index ef31776..0000000
--- a/dashboard/src/features/hosts/dialogs/settings/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { type FC } from "react";
-import {
- SettingsDialogProps,
- SettingsDialog,
- Table,
- TableBody,
- TableRowWithCell,
-} from "@marzneshin/components";
-import { useTranslation } from "react-i18next";
-import { HostType } from "../..";
-
-interface HostsSettingsDialogProps extends SettingsDialogProps {
- onOpenChange: (state: boolean) => void;
- onClose: () => void;
- open: boolean;
- entity: HostType;
-}
-
-export const HostSettingsDialog: FC<HostsSettingsDialogProps> = ({
- onOpenChange,
- open,
- entity,
- onClose,
-}) => {
- const { t } = useTranslation();
-
- return (
- <SettingsDialog open={open} onClose={onClose} onOpenChange={onOpenChange}>
- <Table>
- <TableBody>
- <TableRowWithCell label={t("remark")} value={entity.remark} />
- <TableRowWithCell label={t("address")} value={entity.address} />
- <TableRowWithCell label={t("port")} value={entity.port} />
- <TableRowWithCell label={t("host")} value={entity.host} />
- <TableRowWithCell label={t("path")} value={entity.path} />
- <TableRowWithCell label={t("sni")} value={entity.sni} />
- <TableRowWithCell label={t("alpn")} value={entity.alpn} />
- </TableBody>
- </Table>
- </SettingsDialog>
- );
-};
diff --git a/dashboard/src/features/hosts/schema/get-default.ts b/dashboard/src/features/hosts/schema/get-default.ts
deleted file mode 100644
index 067c0bc..0000000
--- a/dashboard/src/features/hosts/schema/get-default.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { HostSchemaType } from "..";
-
-export const getDefaultValues = (): HostSchemaType => {
- return {
- host: '',
- sni: '',
- port: 8080,
- path: '',
- address: '',
- remark: '',
- fragment: null,
- mux: false,
- security: 'inbound_default',
- alpn: "",
- allowinsecure: false,
- fingerprint: "",
- is_disabled: false,
- }
-};
diff --git a/dashboard/src/features/hosts/schema/index.ts b/dashboard/src/features/hosts/schema/index.ts
deleted file mode 100644
index 8bd749f..0000000
--- a/dashboard/src/features/hosts/schema/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './get-default'
-export * from './hosts-schema'
diff --git a/dashboard/src/features/hosts/services/host-mutation.dto.ts b/dashboard/src/features/hosts/services/host-mutation.dto.ts
deleted file mode 100644
index 3343905..0000000
--- a/dashboard/src/features/hosts/services/host-mutation.dto.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { HostType } from "@marzneshin/features/hosts";
-
-export interface HostRequestDto {
- inboundId: number
- host: HostType
-}
-
-export interface HostUpdateRequestDto {
- hostId: number
- host: HostType
-}
diff --git a/dashboard/src/features/hosts/types/index.ts b/dashboard/src/features/hosts/types/index.ts
deleted file mode 100644
index c5473b6..0000000
--- a/dashboard/src/features/hosts/types/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { z } from "zod";
-import { HostSchema } from "@marzneshin/features/hosts";
-
-export type HostSchemaType = z.infer<typeof HostSchema>;
-export type HostType = HostSchemaType & { id?: number };
diff --git a/dashboard/src/features/language-switch/index.tsx b/dashboard/src/features/language-switch/index.tsx
index 51d7271..3702ab3 100644
--- a/dashboard/src/features/language-switch/index.tsx
+++ b/dashboard/src/features/language-switch/index.tsx
@@ -8,7 +8,7 @@ import {
import { Languages } from "lucide-react";
import { FC } from "react";
import { useTranslation } from "react-i18next";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
const LanguageItem = ({ language, title }: { language: string, title: string }) => {
const { i18n } = useTranslation();
diff --git a/dashboard/src/features/sidebar/sidebar.tsx b/dashboard/src/features/sidebar/sidebar.tsx
index e4488a3..08f4931 100644
--- a/dashboard/src/features/sidebar/sidebar.tsx
+++ b/dashboard/src/features/sidebar/sidebar.tsx
@@ -2,10 +2,10 @@ import {
Sidebar,
type SidebarItem,
} from "@marzneshin/components";
-import { useIsCurrentRoute } from "@marzneshin/hooks";
+import { useIsCurrentRoute } from "@marzneshin/common/hooks";
import type { FC } from "react";
import { sidebarItems as sidebarItemsSudoAdmin, sidebarItemsNonSudoAdmin } from ".";
-import { projectInfo, cn } from "@marzneshin/utils";
+import { projectInfo, cn } from "@marzneshin/common/utils";
import { useAuth } from "@marzneshin/features/auth";
import { SupportUs } from "@marzneshin/features/support-us";
diff --git a/dashboard/src/features/support-us/card.tsx b/dashboard/src/features/support-us/card.tsx
index dc50284..8036a12 100644
--- a/dashboard/src/features/support-us/card.tsx
+++ b/dashboard/src/features/support-us/card.tsx
@@ -2,7 +2,7 @@ import type { FC, HTMLAttributes } from "react";
import { SupportUsVariation } from "./types";
import { X, HeartHandshake } from "lucide-react";
import { Button, Card, CardTitle, CardContent } from "@marzneshin/components";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { useTranslation } from "react-i18next";
export interface SupportUsCardProps extends HTMLAttributes<HTMLDivElement> {
diff --git a/dashboard/src/features/support-us/popover.tsx b/dashboard/src/features/support-us/popover.tsx
index d343f47..9bd079a 100644
--- a/dashboard/src/features/support-us/popover.tsx
+++ b/dashboard/src/features/support-us/popover.tsx
@@ -1,7 +1,7 @@
import { HeartHandshake } from "lucide-react";
import { Button, PopoverTrigger, Popover, PopoverContent } from "@marzneshin/components";
import { type FC, type HTMLAttributes } from "react";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { useTranslation } from "react-i18next";
import { DonationButton } from "./donation-button";
diff --git a/dashboard/src/features/theme-switch/theme-toggle/index.tsx b/dashboard/src/features/theme-switch/theme-toggle/index.tsx
index 6c30410..99e474e 100644
--- a/dashboard/src/features/theme-switch/theme-toggle/index.tsx
+++ b/dashboard/src/features/theme-switch/theme-toggle/index.tsx
@@ -8,7 +8,7 @@ import {
} from "@marzneshin/components";
import { useTheme, Theme } from "../theme-provider";
import { useTranslation } from "react-i18next";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
const ThemeItem = ({ schema }: { schema: Theme }) => {
const { theme, setTheme } = useTheme();
diff --git a/dashboard/src/features/total-traffic-widget/api/total-traffic.query.ts b/dashboard/src/features/total-traffic-widget/api/total-traffic.query.ts
index 0bb722d..207885c 100644
--- a/dashboard/src/features/total-traffic-widget/api/total-traffic.query.ts
+++ b/dashboard/src/features/total-traffic-widget/api/total-traffic.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
export type UsageMetric = number[];
diff --git a/dashboard/src/libs/dialog/index.ts b/dashboard/src/libs/dialog/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/dashboard/src/libs/dialog/mutation/index.ts b/dashboard/src/libs/dialog/mutation/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/dashboard/src/libs/index.ts b/dashboard/src/libs/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx b/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx
index 88d72bc..37036cd 100644
--- a/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx
+++ b/dashboard/src/modules/admins/components/dialogs/mutation/index.tsx
@@ -17,7 +17,7 @@ import {
AdminCreateSchema,
AdminType,
} from "@marzneshin/modules/admins";
-import { ServicesField } from "@marzneshin/features/services";
+import { ServicesField } from "@marzneshin/modules/services";
import { UsernameField } from "@marzneshin/modules/users";
import {
PasswordField,
@@ -27,7 +27,7 @@ import {
SudoPrivilageField,
AllServicesAccessField,
} from "./fields";
-import { useMutationDialog, MutationDialogProps } from "@marzneshin/hooks";
+import { useMutationDialog, MutationDialogProps } from "@marzneshin/common/hooks";
export const AdminsMutationDialog: FC<MutationDialogProps<AdminType>> = ({
onClose,
diff --git a/dashboard/src/modules/admins/services/admin.query.ts b/dashboard/src/modules/admins/services/admin.query.ts
index 4612322..3056a4d 100644
--- a/dashboard/src/modules/admins/services/admin.query.ts
+++ b/dashboard/src/modules/admins/services/admin.query.ts
@@ -1,5 +1,5 @@
import { queryOptions, useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import type { AdminType } from "../types";
export async function fetchAdmin({
diff --git a/dashboard/src/modules/admins/services/admins.query.ts b/dashboard/src/modules/admins/services/admins.query.ts
index 81c9c79..660a1e4 100644
--- a/dashboard/src/modules/admins/services/admins.query.ts
+++ b/dashboard/src/modules/admins/services/admins.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { AdminType } from "@marzneshin/modules/admins";
import {
FetchEntityReturn,
diff --git a/dashboard/src/modules/admins/services/create-admin.mutate.ts b/dashboard/src/modules/admins/services/create-admin.mutate.ts
index fed6527..3377bf6 100644
--- a/dashboard/src/modules/admins/services/create-admin.mutate.ts
+++ b/dashboard/src/modules/admins/services/create-admin.mutate.ts
@@ -1,6 +1,6 @@
import { AdminType, AdminMutationType, AdminsQueryFetchKey } from "@marzneshin/modules/admins";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/admins/services/delete-admin.mutate.ts b/dashboard/src/modules/admins/services/delete-admin.mutate.ts
index d00e7b3..7b83f04 100644
--- a/dashboard/src/modules/admins/services/delete-admin.mutate.ts
+++ b/dashboard/src/modules/admins/services/delete-admin.mutate.ts
@@ -1,6 +1,6 @@
import { AdminType, AdminsQueryFetchKey } from "@marzneshin/modules/admins";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/admins/services/update-admin.mutate.ts b/dashboard/src/modules/admins/services/update-admin.mutate.ts
index e2ca624..344239a 100644
--- a/dashboard/src/modules/admins/services/update-admin.mutate.ts
+++ b/dashboard/src/modules/admins/services/update-admin.mutate.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/hosts/components/index.ts b/dashboard/src/modules/hosts/components/index.ts
new file mode 100644
index 0000000..758d22e
--- /dev/null
+++ b/dashboard/src/modules/hosts/components/index.ts
@@ -0,0 +1,2 @@
+export * from "./popover-guide"
+export * from "./settings-section"
diff --git a/dashboard/src/features/hosts/components/popover-guide.tsx b/dashboard/src/modules/hosts/components/popover-guide.tsx
similarity index 100%
rename from dashboard/src/features/hosts/components/popover-guide.tsx
rename to dashboard/src/modules/hosts/components/popover-guide.tsx
diff --git a/dashboard/src/modules/hosts/components/settings-section.tsx b/dashboard/src/modules/hosts/components/settings-section.tsx
new file mode 100644
index 0000000..912d2ad
--- /dev/null
+++ b/dashboard/src/modules/hosts/components/settings-section.tsx
@@ -0,0 +1,21 @@
+import { AccordionItem, AccordionTrigger, AccordionContent } from '@marzneshin/components';
+import { FC, PropsWithChildren } from "react";
+
+interface SettingSectionProps {
+ value: string;
+ triggerText: string;
+}
+
+export const SettingSection: FC<SettingSectionProps & PropsWithChildren> = ({
+ value, triggerText, children
+}) => {
+ return (
+ <AccordionItem
+ className="data-[state=open]:bg-muted/40 rounded-lg data-[state=close]:border-muted data-[state=open]:border-muted-foreground border-1 px-3"
+ value={value}
+ >
+ <AccordionTrigger>{triggerText}</AccordionTrigger>
+ <AccordionContent>{children}</AccordionContent>
+ </AccordionItem>
+ );
+}
diff --git a/dashboard/src/features/hosts/dialogs/delete-confirmation/index.tsx b/dashboard/src/modules/hosts/dialogs/delete-confirmation/index.tsx
similarity index 97%
rename from dashboard/src/features/hosts/dialogs/delete-confirmation/index.tsx
rename to dashboard/src/modules/hosts/dialogs/delete-confirmation/index.tsx
index 30b1e2f..81f7414 100644
--- a/dashboard/src/features/hosts/dialogs/delete-confirmation/index.tsx
+++ b/dashboard/src/modules/hosts/dialogs/delete-confirmation/index.tsx
@@ -1,6 +1,6 @@
import { DeleteConfirmation } from '@marzneshin/components'
import { type FC, useEffect } from 'react'
-import { HostType, useHostsDeletionMutation } from '@marzneshin/features/hosts'
+import { HostType, useHostsDeletionMutation } from '@marzneshin/modules/hosts'
interface HostsDeleteConfirmationDialogProps {
onOpenChange: (state: boolean) => void
diff --git a/dashboard/src/features/hosts/dialogs/index.ts b/dashboard/src/modules/hosts/dialogs/index.ts
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/index.ts
rename to dashboard/src/modules/hosts/dialogs/index.ts
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/address.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/address.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/address.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/address.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/allow-insecure.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/allow-insecure.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/allow-insecure.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/allow-insecure.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/alpn.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/alpn.tsx
similarity index 95%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/alpn.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/alpn.tsx
index 845bd0d..5b67df3 100644
--- a/dashboard/src/features/hosts/dialogs/mutation/fields/alpn.tsx
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/alpn.tsx
@@ -12,7 +12,7 @@ import {
} from "@marzneshin/components";
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
-import { alpnOptions } from "@marzneshin/features/hosts";
+import { alpnOptions } from "@marzneshin/modules/hosts";
export const AlpnField = () => {
const { t } = useTranslation();
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/fields/common-fields.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/common-fields.tsx
new file mode 100644
index 0000000..055f354
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/common-fields.tsx
@@ -0,0 +1,20 @@
+import {
+ HStack,
+} from "@marzneshin/components";
+import {
+ RemarkField,
+ AddressField,
+ PortField,
+ WeightField,
+} from ".";
+
+export const CommonFields = () => (
+ <>
+ <RemarkField />
+ <HStack className="gap-2 items-start">
+ <AddressField />
+ <PortField />
+ <WeightField />
+ </HStack>
+ </>
+)
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/fields/dns-servers.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/dns-servers.tsx
new file mode 100644
index 0000000..e7fa3d2
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/dns-servers.tsx
@@ -0,0 +1,30 @@
+import {
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+ Input,
+} from "@marzneshin/components";
+import { useFormContext } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+
+export const DNSServersField = () => {
+ const { t } = useTranslation();
+ const form = useFormContext();
+ return (
+ <FormField
+ control={form.control}
+ name="dns_servers"
+ render={({ field }) => (
+ <FormItem className="w-full">
+ <FormLabel>{t("page.hosts.dns-servers")}</FormLabel>
+ <FormControl>
+ <Input {...field} />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ );
+};
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/fingerprint.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/fingerprint.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/fingerprint.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/fingerprint.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/fragment.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/fragment.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/fragment.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/fragment.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/host.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/host.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/host.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/host.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/index.ts b/dashboard/src/modules/hosts/dialogs/mutation/fields/index.ts
similarity index 79%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/index.ts
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/index.ts
index 19d857b..3ff2818 100644
--- a/dashboard/src/features/hosts/dialogs/mutation/fields/index.ts
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/index.ts
@@ -11,3 +11,6 @@ export * from './fingerprint'
export * from './mux'
export * from './fragment'
export * from './weight'
+export * from './common-fields'
+export * from './mtu'
+export * from './dns-servers'
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/is-disabled.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/is-disabled.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/is-disabled.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/is-disabled.tsx
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/fields/mtu.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/mtu.tsx
new file mode 100644
index 0000000..7358f46
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/mtu.tsx
@@ -0,0 +1,28 @@
+import {
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+ Input
+} from "@marzneshin/components";
+import { useFormContext } from "react-hook-form";
+
+export const MtuField = () => {
+ const form = useFormContext()
+ return (
+ <FormField
+ control={form.control}
+ name="mtu"
+ render={({ field }) => (
+ <FormItem className="w-1/3">
+ <FormLabel>MTU</FormLabel>
+ <FormControl>
+ <Input type="number" {...field} />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ )
+}
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/mux.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/mux.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/mux.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/mux.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/path.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/path.tsx
similarity index 84%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/path.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/path.tsx
index 2ebad1e..046ed2f 100644
--- a/dashboard/src/features/hosts/dialogs/mutation/fields/path.tsx
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/path.tsx
@@ -9,7 +9,7 @@ import {
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
-export const PathField = () => {
+export const PathField = ({ label }: { label?: string }) => {
const { t } = useTranslation();
const form = useFormContext();
return (
@@ -18,7 +18,7 @@ export const PathField = () => {
name="path"
render={({ field }) => (
<FormItem className="w-full">
- <FormLabel>{t("path")}</FormLabel>
+ <FormLabel>{label ?? t("path")}</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/port.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/port.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/port.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/port.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/remark.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/remark.tsx
similarity index 95%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/remark.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/remark.tsx
index ed24a74..e0d4377 100644
--- a/dashboard/src/features/hosts/dialogs/mutation/fields/remark.tsx
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/remark.tsx
@@ -9,7 +9,7 @@ import {
PopoverTrigger,
PopoverContent,
} from "@marzneshin/components";
-import { PopoverGuide } from '@marzneshin/features/hosts';
+import { PopoverGuide } from '@marzneshin/modules/hosts';
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { InfoIcon } from 'lucide-react';
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/fields/security.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/security.tsx
new file mode 100644
index 0000000..be30b44
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/fields/security.tsx
@@ -0,0 +1,66 @@
+import {
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@marzneshin/components";
+import { useEffect, useState } from "react";
+import { useFormContext } from "react-hook-form";
+import { useTranslation } from "react-i18next";
+import { AllowInsecureField, AlpnField, FingerprintField, SniField } from ".";
+
+export const SecurityFields = () => {
+ const { t } = useTranslation();
+ const form = useFormContext();
+ const security = form.watch().security;
+
+ const [extraSecurity, setExtraSecurity] = useState<boolean>(
+ ["tls", "inbound_default"].includes(security),
+ );
+ useEffect(() => {
+ setExtraSecurity(["tls", "inbound_default"].includes(security));
+ }, [security, setExtraSecurity]);
+
+ return (
+ <>
+ <FormField
+ control={form.control}
+ name="security"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>{t("security")}</FormLabel>
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
+ <FormControl>
+ <SelectTrigger>
+ <SelectValue placeholder="Select a verified email to display" />
+ </SelectTrigger>
+ </FormControl>
+ <SelectContent>
+ <SelectItem value="none">None</SelectItem>
+ <SelectItem value="tls">TLS</SelectItem>
+ <SelectItem value="inbound_default">Inbound Default</SelectItem>
+ </SelectContent>
+ </Select>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+ {extraSecurity && (
+ <>
+ <SniField />
+ <div className="flex flex-row w-full gap-2">
+ <AlpnField />
+ <FingerprintField />
+ </div>
+ <AllowInsecureField />
+ </>
+ )}
+ </>
+ );
+};
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/sni.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/sni.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/sni.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/sni.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/fields/weight.tsx b/dashboard/src/modules/hosts/dialogs/mutation/fields/weight.tsx
similarity index 100%
rename from dashboard/src/features/hosts/dialogs/mutation/fields/weight.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/fields/weight.tsx
diff --git a/dashboard/src/features/hosts/dialogs/mutation/index.tsx b/dashboard/src/modules/hosts/dialogs/mutation/index.tsx
similarity index 60%
rename from dashboard/src/features/hosts/dialogs/mutation/index.tsx
rename to dashboard/src/modules/hosts/dialogs/mutation/index.tsx
index a49a26c..35e9619 100644
--- a/dashboard/src/features/hosts/dialogs/mutation/index.tsx
+++ b/dashboard/src/modules/hosts/dialogs/mutation/index.tsx
@@ -6,41 +6,29 @@ import {
DialogHeader,
Form,
Button,
- Accordion,
- AccordionContent,
- AccordionItem,
- AccordionTrigger,
ScrollArea,
- HStack,
} from "@marzneshin/components";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslation } from "react-i18next";
import {
- HostSchema,
- getDefaultValues,
useHostsCreationMutation,
useHostsUpdateMutation,
- type HostType,
-} from "@marzneshin/features/hosts";
-import {
- RemarkField,
- AddressField,
- PortField,
- HostField,
- MuxField,
- FragmentField,
- PathField,
- WeightField,
- SecurityFields,
-} from "./fields";
-import { useDialog, MutationDialogProps } from "@marzneshin/hooks";
+ type HostWithProfileType,
+ type HostWithProfileSchemaType
+} from "@marzneshin/modules/hosts";
+import { useDialog, type MutationDialogProps } from "@marzneshin/common/hooks";
+import { ProtocolType } from "@marzneshin/modules/inbounds";
+import { useProfileStrategy } from "./profiles";
-interface HostMutationDialogProps extends MutationDialogProps<HostType> {
+interface HostMutationDialogProps extends MutationDialogProps<HostWithProfileType> {
inboundId?: number;
+ protocol?: ProtocolType;
}
-const transformFormValue = (values: HostType) => {
+const transformFormValue = (values: any) => {
+ if (!(values.alpn && values.fingerprint))
+ return values;
const port = values.port === "" ? null : values.port;
const alpn = values.alpn === "none" ? "" : values.alpn;
const fingerprint = values.fingerprint === "none" ? "" : values.fingerprint;
@@ -48,20 +36,22 @@ const transformFormValue = (values: HostType) => {
};
export const HostsMutationDialog: FC<HostMutationDialogProps> = ({
- inboundId,
entity,
+ inboundId,
onClose,
+ protocol,
}) => {
const [open, onOpenChange] = useDialog(true);
- const form = useForm({
- defaultValues: entity ? entity : getDefaultValues(),
- resolver: zodResolver(HostSchema),
+ const [Schema, ProfileFields, defaultValue] = useProfileStrategy(protocol)
+ const form = useForm<HostWithProfileSchemaType>({
+ defaultValues: entity ? entity : defaultValue,
+ resolver: zodResolver(Schema),
});
const updateMutation = useHostsUpdateMutation();
const createMutation = useHostsCreationMutation();
const { t } = useTranslation();
- const submit = (values: HostType) => {
+ const submit = (values: HostWithProfileSchemaType) => {
const host = transformFormValue(values);
if (entity && entity.id !== undefined) {
updateMutation.mutate({ hostId: entity.id, host });
@@ -78,8 +68,8 @@ export const HostsMutationDialog: FC<HostMutationDialogProps> = ({
useEffect(() => {
if (entity) form.reset(entity);
- else form.reset(getDefaultValues());
- }, [entity, form, open]);
+ else form.reset(defaultValue);
+ }, [entity, form, open, defaultValue]);
return (
<Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
@@ -97,26 +87,7 @@ export const HostsMutationDialog: FC<HostMutationDialogProps> = ({
onSubmit={form.handleSubmit(submit)}
className="h-full flex flex-col justify-between"
>
- <RemarkField />
- <HStack className="gap-2 items-start">
- <AddressField />
- <PortField />
- </HStack>
- <Accordion type="single" collapsible>
- <AccordionItem value="item-1">
- <AccordionTrigger>{t("advanced-options")}</AccordionTrigger>
- <AccordionContent>
- <div className="flex flex-row gap-2 items-start">
- <HostField />
- <PathField />
- <WeightField />
- </div>
- <FragmentField />
- <MuxField />
- <SecurityFields />
- </AccordionContent>
- </AccordionItem>
- </Accordion>
+ <ProfileFields />
<Button
className="mt-3 w-full font-semibold"
type="submit"
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/default.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/default.ts
new file mode 100644
index 0000000..916d0a0
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/default.ts
@@ -0,0 +1,18 @@
+import { GeneralSchemaType } from "./schema";
+
+export const generalProfileDefaultValue: GeneralSchemaType = {
+ host: '',
+ sni: '',
+ port: 8080,
+ path: '',
+ address: '',
+ remark: '',
+ fragment: null,
+ mux: false,
+ security: 'inbound_default',
+ alpn: "",
+ allowinsecure: false,
+ fingerprint: "",
+ is_disabled: false,
+};
+
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/index.tsx b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/index.tsx
new file mode 100644
index 0000000..7e663b7
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/index.tsx
@@ -0,0 +1,41 @@
+import {
+ CommonFields,
+ HostField,
+ MuxField,
+ FragmentField,
+ PathField,
+ SecurityFields,
+} from "../../fields";
+import {
+ Accordion,
+ HStack
+} from "@marzneshin/components";
+import { SettingSection } from "@marzneshin/modules/hosts"
+import { useTranslation } from "react-i18next";
+
+export const GeneralProfileFields = () => {
+ const { t } = useTranslation();
+ return (
+ <div className="space-y-2">
+ <CommonFields />
+ <Accordion className="space-y-2" type="single" collapsible>
+ <SettingSection value="network" triggerText={t("page.hosts.network-settings")}>
+ <HStack>
+ <HostField />
+ <PathField />
+ </HStack>
+ </SettingSection>
+ <SettingSection value="camouflage" triggerText={t("page.hosts.camouflage-settings")}>
+ <FragmentField />
+ <MuxField />
+ </SettingSection>
+ <SettingSection value="security" triggerText={t("page.hosts.security-settings")}>
+ <SecurityFields />
+ </SettingSection>
+ </Accordion>
+ </div>
+ )
+}
+
+export * from "./schema";
+export * from "./default";
diff --git a/dashboard/src/features/hosts/schema/hosts-schema.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/schema.ts
similarity index 73%
rename from dashboard/src/features/hosts/schema/hosts-schema.ts
rename to dashboard/src/modules/hosts/dialogs/mutation/profiles/general/schema.ts
index 3de8055..1a70683 100644
--- a/dashboard/src/features/hosts/schema/hosts-schema.ts
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/general/schema.ts
@@ -1,4 +1,5 @@
import { z } from "zod";
+import { HostSchema, TlsSchema } from "@marzneshin/modules/hosts";
import i18n from "i18next";
const numberInterval = (v: string | null | undefined) => {
@@ -19,22 +20,8 @@ export const alpnOptions = [
"h3,h2,http/1.1"
]
-export const HostSchema = z.object({
- remark: z.string().min(1, "Remark is required"),
- address: z.string().min(1, "Address is required"),
- weight: z.coerce
- .number().int()
- .nullable()
- .optional(),
- port: z.coerce
- .number()
- .gte(1, "Port must be more than 1")
- .lte(65535, "Port can not be more than 65535")
- .or(z.string())
- .nullable()
- .optional(),
+export const GeneralSchema = HostSchema.merge(TlsSchema).extend({
path: z.string().nullable().optional(),
- sni: z.string().nullable().optional(),
host: z.string().nullable().optional(),
mux: z.boolean().nullable().optional(),
fragment: z
@@ -63,11 +50,6 @@ export const HostSchema = z.object({
security: z
.enum(["inbound_default", "none", "tls"])
.default("inbound_default"),
- alpn: z
- .enum(["", ...alpnOptions])
- .optional()
- .default("none"),
- allowinsecure: z.boolean().default(false).optional(),
fingerprint: z
.enum([
"",
@@ -87,3 +69,6 @@ export const HostSchema = z.object({
.default("none"),
is_disabled: z.boolean(),
});
+
+
+export type GeneralSchemaType = z.infer<typeof GeneralSchema>;
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/default.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/default.ts
new file mode 100644
index 0000000..eece0b6
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/default.ts
@@ -0,0 +1,11 @@
+import { Hysteria2SchemaType } from "./schema";
+
+export const hysteria2ProfileDefaultValue: Hysteria2SchemaType = {
+ sni: '',
+ port: 8080,
+ path: '',
+ address: '',
+ remark: '',
+ alpn: "",
+ allowinsecure: false,
+};
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/index.tsx b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/index.tsx
new file mode 100644
index 0000000..8386871
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/index.tsx
@@ -0,0 +1,27 @@
+import {
+ CommonFields,
+ PathField,
+} from "../../fields";
+import {
+ TlsFields
+} from "../../sections";
+import {
+ Accordion,
+} from "@marzneshin/components";
+import { useTranslation } from "react-i18next";
+
+export const Hysteria2ProfileFields = () => {
+ const { t } = useTranslation();
+ return (
+ <div className="space-y-2">
+ <CommonFields />
+ <PathField label={t("page.hosts.obfuscation-password")} />
+ <Accordion className="space-y-2" type="single" collapsible>
+ <TlsFields />
+ </Accordion>
+ </div>
+ )
+}
+
+export * from "./schema";
+export * from "./default";
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/schema.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/schema.ts
new file mode 100644
index 0000000..0fe6039
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/hysteria2/schema.ts
@@ -0,0 +1,11 @@
+import { z } from "zod";
+import { HostSchema, TlsSchema } from "@marzneshin/modules/hosts";
+
+export const Hysteria2Schema =
+ HostSchema.merge(
+ TlsSchema.extend({
+ path: z.string().nullable().optional(),
+ }))
+ ;
+
+export type Hysteria2SchemaType = z.infer<typeof Hysteria2Schema>;
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/index.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/index.ts
new file mode 100644
index 0000000..6b18c09
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/index.ts
@@ -0,0 +1,5 @@
+export * from "./use-profile-strategy"
+export * from "./wireguard"
+export * from "./hysteria2"
+export * from "./general"
+export * from "./tuic"
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/default.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/default.ts
new file mode 100644
index 0000000..e73bb66
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/default.ts
@@ -0,0 +1,11 @@
+import { TuicSchemaType } from "./schema";
+
+export const tuicProfileDefaultValue: TuicSchemaType = {
+ sni: '',
+ port: 8080,
+ address: '',
+ weight: 1,
+ remark: '',
+ alpn: '',
+ allowinsecure: false,
+};
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/index.tsx b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/index.tsx
new file mode 100644
index 0000000..732c69b
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/index.tsx
@@ -0,0 +1,18 @@
+import {
+ CommonFields,
+} from "../../fields";
+import {
+ TlsFields
+} from "../../sections";
+
+export const TuicProfileFields = () => {
+ return (
+ <>
+ <CommonFields />
+ <TlsFields />
+ </>
+ )
+}
+
+export * from "./schema";
+export * from "./default";
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/schema.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/schema.ts
new file mode 100644
index 0000000..cdcbf53
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/tuic/schema.ts
@@ -0,0 +1,6 @@
+import { z } from "zod";
+import { HostSchema, TlsSchema } from "@marzneshin/modules/hosts";
+
+export const TuicSchema = HostSchema.merge(TlsSchema);
+
+export type TuicSchemaType = z.infer<typeof TuicSchema>;
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/use-profile-strategy.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/use-profile-strategy.ts
new file mode 100644
index 0000000..b86e6f0
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/use-profile-strategy.ts
@@ -0,0 +1,34 @@
+import { ProtocolType } from "@marzneshin/modules/inbounds";
+import { FC } from "react";
+import { GeneralSchema, GeneralProfileFields, generalProfileDefaultValue } from "./general";
+import { WireguardSchema, WireguardProfileFields, wireguardProfileDefaultValue } from "./wireguard";
+import { Hysteria2Schema, Hysteria2ProfileFields, hysteria2ProfileDefaultValue } from "./hysteria2";
+import { TuicSchema, TuicProfileFields, tuicProfileDefaultValue } from "./tuic";
+
+type ProfileSchema = typeof GeneralSchema | typeof WireguardSchema | typeof Hysteria2Schema | typeof TuicSchema;
+type ProfileFields = FC;
+
+/**
+ * @param protocol - Inbound protocol of host
+ * @returns [schema, fields, default values] - An array of schema, profile fields, and their default
+ */
+export const useProfileStrategy = (
+ protocol?: ProtocolType
+): [ProfileSchema, ProfileFields, object] => {
+ if (!protocol)
+ return [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue]
+
+ const profileMap: { [key in ProtocolType]: [ProfileSchema, ProfileFields, object] } = {
+ vless: [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue],
+ vmess: [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue],
+ trojan: [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue],
+ shadowsocks: [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue],
+ shadowsocks2022: [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue],
+ wireguard: [WireguardSchema, WireguardProfileFields, wireguardProfileDefaultValue],
+ hysteria2: [Hysteria2Schema, Hysteria2ProfileFields, hysteria2ProfileDefaultValue],
+ tuic: [TuicSchema, TuicProfileFields, tuicProfileDefaultValue],
+ };
+
+ const [Schema, Fields, defaultValues] = profileMap[protocol] || [GeneralSchema, GeneralProfileFields, generalProfileDefaultValue];
+ return [Schema, Fields, defaultValues];
+};
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/default.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/default.ts
new file mode 100644
index 0000000..f0c9788
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/default.ts
@@ -0,0 +1,10 @@
+import { WireguardSchemaType } from "..";
+
+export const wireguardProfileDefaultValue: WireguardSchemaType = {
+ port: 8080,
+ path: '',
+ address: '',
+ remark: '',
+ dns_servers: '',
+ mtu: undefined,
+};
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/index.tsx b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/index.tsx
new file mode 100644
index 0000000..512c166
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/index.tsx
@@ -0,0 +1,33 @@
+import {
+ CommonFields,
+ MtuField,
+ DNSServersField,
+ PathField,
+} from "../../fields";
+import {
+ Accordion,
+ HStack
+} from "@marzneshin/components";
+import { SettingSection } from "@marzneshin/modules/hosts"
+import { useTranslation } from "react-i18next";
+
+export const WireguardProfileFields = () => {
+ const { t } = useTranslation();
+ return (
+ <>
+ <CommonFields />
+ <Accordion type="single" collapsible>
+ <SettingSection value="wireguard" triggerText={t("wireguard")}>
+ <HStack>
+ <PathField label={t("page.hosts.server-public-key")} />
+ <MtuField />
+ </HStack>
+ <DNSServersField />
+ </SettingSection>
+ </Accordion>
+ </>
+ )
+}
+
+export * from "./schema";
+export * from "./default";
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/schema.ts b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/schema.ts
new file mode 100644
index 0000000..cb8fee9
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/profiles/wireguard/schema.ts
@@ -0,0 +1,17 @@
+import { z } from "zod";
+import { HostSchema } from "@marzneshin/modules/hosts";
+
+export const WireguardSchema = HostSchema.extend({
+ path: z.string().nullable().optional(),
+ mtu: z.coerce
+ .number()
+ .or(z.string())
+ .nullable()
+ .optional(),
+ dns_servers: z.coerce
+ .string()
+ .nullable()
+ .optional(),
+});
+
+export type WireguardSchemaType = z.infer<typeof WireguardSchema>;
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/sections/index.ts b/dashboard/src/modules/hosts/dialogs/mutation/sections/index.ts
new file mode 100644
index 0000000..5ff5dd0
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/sections/index.ts
@@ -0,0 +1 @@
+export * from "./tls-fields";
diff --git a/dashboard/src/modules/hosts/dialogs/mutation/sections/tls-fields.tsx b/dashboard/src/modules/hosts/dialogs/mutation/sections/tls-fields.tsx
new file mode 100644
index 0000000..15e5515
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/mutation/sections/tls-fields.tsx
@@ -0,0 +1,15 @@
+import { AllowInsecureField, AlpnField, SniField } from "../fields";
+import { SettingSection } from "@marzneshin/modules/hosts/components";
+import { useTranslation } from "react-i18next";
+import { FC } from 'react'
+
+export const TlsFields: FC = () => {
+ const { t } = useTranslation();
+ return (
+ <SettingSection value="tls-settings" triggerText={t("page.hosts.tls-config")}>
+ <SniField />
+ <AlpnField />
+ <AllowInsecureField />
+ </SettingSection>
+ )
+}
diff --git a/dashboard/src/modules/hosts/dialogs/settings/index.tsx b/dashboard/src/modules/hosts/dialogs/settings/index.tsx
new file mode 100644
index 0000000..2839b9f
--- /dev/null
+++ b/dashboard/src/modules/hosts/dialogs/settings/index.tsx
@@ -0,0 +1,67 @@
+import { type FC } from "react";
+import {
+ SettingsDialogProps,
+ SettingsDialog,
+ Table,
+ TableBody,
+ TableRowWithCell,
+} from "@marzneshin/components";
+import { useTranslation } from "react-i18next";
+
+interface HostWithProfileSchemaType {
+ remark: string;
+ address: string;
+ weight?: number | null;
+ port?: string | number | null;
+ host?: string;
+ path?: string;
+ sni?: string;
+ alpn?: string;
+}
+
+interface HostsSettingsDialogProps extends SettingsDialogProps {
+ onOpenChange: (state: boolean) => void;
+ onClose: () => void;
+ open: boolean;
+ entity: HostWithProfileSchemaType;
+}
+
+export const HostSettingsDialog: FC<HostsSettingsDialogProps> = ({
+ onOpenChange,
+ open,
+ entity,
+ onClose,
+}) => {
+ const { t } = useTranslation();
+
+ return (
+ <SettingsDialog open={open} onClose={onClose} onOpenChange={onOpenChange}>
+ <Table>
+ <TableBody>
+ <TableRowWithCell label={t("remark")} value={entity.remark} />
+ <TableRowWithCell label={t("address")} value={entity.address} />
+ <TableRowWithCell
+ label={t("port")}
+ value={entity.port?.toString() ?? ""}
+ />
+ <TableRowWithCell
+ label={t("host")}
+ value={entity.host ?? ""}
+ />
+ <TableRowWithCell
+ label={t("path")}
+ value={entity.path ?? ""}
+ />
+ <TableRowWithCell
+ label={t("sni")}
+ value={entity.sni ?? ""}
+ />
+ <TableRowWithCell
+ label={t("alpn")}
+ value={entity.alpn ?? ""}
+ />
+ </TableBody>
+ </Table>
+ </SettingsDialog>
+ );
+};
diff --git a/dashboard/src/modules/hosts/domain/host-with-profile.type.ts b/dashboard/src/modules/hosts/domain/host-with-profile.type.ts
new file mode 100644
index 0000000..5fedf45
--- /dev/null
+++ b/dashboard/src/modules/hosts/domain/host-with-profile.type.ts
@@ -0,0 +1,18 @@
+import {
+ GeneralSchemaType,
+ WireguardSchemaType,
+ Hysteria2SchemaType,
+ TuicSchemaType
+} from "../dialogs/mutation/profiles";
+import { HostSchemaType } from "./host";
+import { ProtocolType } from "@marzneshin/modules/inbounds";
+
+export type HostWithProfileSchemaType =
+ HostSchemaType
+ | GeneralSchemaType
+ | WireguardSchemaType
+ | Hysteria2SchemaType
+ | TuicSchemaType;
+
+
+export type HostWithProfileType = HostWithProfileSchemaType & { id?: number, inboundId?: number, protocol: ProtocolType };
diff --git a/dashboard/src/modules/hosts/domain/host.ts b/dashboard/src/modules/hosts/domain/host.ts
new file mode 100644
index 0000000..14db109
--- /dev/null
+++ b/dashboard/src/modules/hosts/domain/host.ts
@@ -0,0 +1,22 @@
+import { z } from "zod";
+import { ProtocolType } from "@marzneshin/modules/inbounds";
+
+export const HostSchema = z.object({
+ remark: z.string().min(1, "Remark is required"),
+ address: z.string().min(1, "Address is required"),
+ weight: z.coerce
+ .number().int()
+ .nullable()
+ .optional(),
+ port: z.coerce
+ .number()
+ .gte(1, "Port must be more than 1")
+ .lte(65535, "Port can not be more than 65535")
+ .or(z.string())
+ .nullable()
+ .optional(),
+});
+
+
+export type HostSchemaType = z.infer<typeof HostSchema>;
+export type HostType = HostSchemaType & { id?: number, inboundId?: number, protocol: ProtocolType };
diff --git a/dashboard/src/modules/hosts/domain/index.ts b/dashboard/src/modules/hosts/domain/index.ts
new file mode 100644
index 0000000..18f6dbd
--- /dev/null
+++ b/dashboard/src/modules/hosts/domain/index.ts
@@ -0,0 +1,3 @@
+export * from "./host"
+export * from "./host-with-profile.type"
+export * from "./tls"
diff --git a/dashboard/src/modules/hosts/domain/tls.ts b/dashboard/src/modules/hosts/domain/tls.ts
new file mode 100644
index 0000000..e86881d
--- /dev/null
+++ b/dashboard/src/modules/hosts/domain/tls.ts
@@ -0,0 +1,22 @@
+import { z } from "zod";
+
+export const alpnOptions = [
+ "none",
+ "h2",
+ "h3",
+ "h3,h2",
+ "http/1.1",
+ "h2,http/1.1",
+ "h3,h2,http/1.1"
+]
+
+export const TlsSchema = z.object({
+ sni: z.string().nullable().optional(),
+ alpn: z
+ .enum(["", ...alpnOptions])
+ .optional()
+ .default("none"),
+ allowinsecure: z.boolean().default(false).optional(),
+});
+
+export type TlsSchemaType = z.infer<typeof TlsSchema>;
diff --git a/dashboard/src/features/hosts/index.ts b/dashboard/src/modules/hosts/index.ts
similarity index 74%
rename from dashboard/src/features/hosts/index.ts
rename to dashboard/src/modules/hosts/index.ts
index 83191d3..8012aac 100644
--- a/dashboard/src/features/hosts/index.ts
+++ b/dashboard/src/modules/hosts/index.ts
@@ -1,6 +1,5 @@
-export * from './types'
export * from './tables'
-export * from './schema'
+export * from './domain'
export * from './services'
export * from './dialogs'
export * from './router-context'
diff --git a/dashboard/src/features/hosts/router-context/index.ts b/dashboard/src/modules/hosts/router-context/index.ts
similarity index 84%
rename from dashboard/src/features/hosts/router-context/index.ts
rename to dashboard/src/modules/hosts/router-context/index.ts
index 53cab01..ad26684 100644
--- a/dashboard/src/features/hosts/router-context/index.ts
+++ b/dashboard/src/modules/hosts/router-context/index.ts
@@ -1,5 +1,5 @@
import { createContext, useContext } from "react";
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
interface RouterHostContextProps {
host: HostType;
diff --git a/dashboard/src/features/hosts/services/create-host.mutate.ts b/dashboard/src/modules/hosts/services/create-host.mutate.ts
similarity index 91%
rename from dashboard/src/features/hosts/services/create-host.mutate.ts
rename to dashboard/src/modules/hosts/services/create-host.mutate.ts
index 23ec6d3..1e459ec 100644
--- a/dashboard/src/features/hosts/services/create-host.mutate.ts
+++ b/dashboard/src/modules/hosts/services/create-host.mutate.ts
@@ -1,6 +1,6 @@
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import { HostRequestDto } from "./host-mutation.dto";
diff --git a/dashboard/src/features/hosts/services/delete-host.mutate.ts b/dashboard/src/modules/hosts/services/delete-host.mutate.ts
similarity index 90%
rename from dashboard/src/features/hosts/services/delete-host.mutate.ts
rename to dashboard/src/modules/hosts/services/delete-host.mutate.ts
index 4983928..d82bad7 100644
--- a/dashboard/src/features/hosts/services/delete-host.mutate.ts
+++ b/dashboard/src/modules/hosts/services/delete-host.mutate.ts
@@ -1,6 +1,6 @@
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/hosts/services/host-mutation.dto.ts b/dashboard/src/modules/hosts/services/host-mutation.dto.ts
new file mode 100644
index 0000000..b29e14e
--- /dev/null
+++ b/dashboard/src/modules/hosts/services/host-mutation.dto.ts
@@ -0,0 +1,11 @@
+import { HostWithProfileSchemaType } from "@marzneshin/modules/hosts";
+
+export interface HostRequestDto {
+ inboundId: number
+ host: HostWithProfileSchemaType
+}
+
+export interface HostUpdateRequestDto {
+ hostId: number
+ host: HostWithProfileSchemaType
+}
diff --git a/dashboard/src/features/hosts/services/host.query.ts b/dashboard/src/modules/hosts/services/host.query.ts
similarity index 81%
rename from dashboard/src/features/hosts/services/host.query.ts
rename to dashboard/src/modules/hosts/services/host.query.ts
index 27f50ab..550aaad 100644
--- a/dashboard/src/features/hosts/services/host.query.ts
+++ b/dashboard/src/modules/hosts/services/host.query.ts
@@ -1,6 +1,6 @@
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
export async function fetchHost({ queryKey }: { queryKey: [string, number] }): Promise<HostType> {
return fetch(`/inbounds/hosts/${queryKey[1]}`);
diff --git a/dashboard/src/features/hosts/services/hosts.query.ts b/dashboard/src/modules/hosts/services/hosts.query.ts
similarity index 92%
rename from dashboard/src/features/hosts/services/hosts.query.ts
rename to dashboard/src/modules/hosts/services/hosts.query.ts
index 6683bbb..1977752 100644
--- a/dashboard/src/features/hosts/services/hosts.query.ts
+++ b/dashboard/src/modules/hosts/services/hosts.query.ts
@@ -1,6 +1,6 @@
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import {
FetchEntityReturn,
UseEntityQueryProps,
diff --git a/dashboard/src/features/hosts/services/inbound.query.ts b/dashboard/src/modules/hosts/services/inbound.query.ts
similarity index 82%
rename from dashboard/src/features/hosts/services/inbound.query.ts
rename to dashboard/src/modules/hosts/services/inbound.query.ts
index cfed55d..686312b 100644
--- a/dashboard/src/features/hosts/services/inbound.query.ts
+++ b/dashboard/src/modules/hosts/services/inbound.query.ts
@@ -1,6 +1,6 @@
-import { InboundType } from "@marzneshin/features/inbounds";
+import { InboundType } from "@marzneshin/modules/inbounds";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
export async function fetchInbound({ queryKey }: { queryKey: [string, number] }): Promise<InboundType> {
return fetch(`/inbounds/${queryKey[1]}`).then((result) => result);
diff --git a/dashboard/src/features/hosts/services/index.ts b/dashboard/src/modules/hosts/services/index.ts
similarity index 100%
rename from dashboard/src/features/hosts/services/index.ts
rename to dashboard/src/modules/hosts/services/index.ts
diff --git a/dashboard/src/features/hosts/services/update-host.mutate.ts b/dashboard/src/modules/hosts/services/update-host.mutate.ts
similarity index 91%
rename from dashboard/src/features/hosts/services/update-host.mutate.ts
rename to dashboard/src/modules/hosts/services/update-host.mutate.ts
index 9cab76f..3d332a8 100644
--- a/dashboard/src/features/hosts/services/update-host.mutate.ts
+++ b/dashboard/src/modules/hosts/services/update-host.mutate.ts
@@ -1,6 +1,6 @@
-import { HostType } from "@marzneshin/features/hosts";
+import { HostType } from "@marzneshin/modules/hosts";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import { HostUpdateRequestDto } from "./host-mutation.dto";
diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/columns.tsx b/dashboard/src/modules/hosts/tables/inbound-hosts/columns.tsx
similarity index 95%
rename from dashboard/src/features/hosts/tables/inbound-hosts/columns.tsx
rename to dashboard/src/modules/hosts/tables/inbound-hosts/columns.tsx
index 706086f..76c9429 100644
--- a/dashboard/src/features/hosts/tables/inbound-hosts/columns.tsx
+++ b/dashboard/src/modules/hosts/tables/inbound-hosts/columns.tsx
@@ -1,5 +1,5 @@
import { ColumnDef } from "@tanstack/react-table"
-import { HostType } from "@marzneshin/features/hosts"
+import { HostType } from "@marzneshin/modules/hosts"
import {
DataTableActionsCell,
DataTableColumnHeader
diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/inbound-not-selected-alert-dialog.tsx b/dashboard/src/modules/hosts/tables/inbound-hosts/inbound-not-selected-alert-dialog.tsx
similarity index 100%
rename from dashboard/src/features/hosts/tables/inbound-hosts/inbound-not-selected-alert-dialog.tsx
rename to dashboard/src/modules/hosts/tables/inbound-hosts/inbound-not-selected-alert-dialog.tsx
diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx b/dashboard/src/modules/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx
similarity index 95%
rename from dashboard/src/features/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx
rename to dashboard/src/modules/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx
index db11920..cac1f0d 100644
--- a/dashboard/src/features/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx
+++ b/dashboard/src/modules/hosts/tables/inbound-hosts/inbound-sidebar-card.tsx
@@ -6,7 +6,7 @@ import {
} from "@marzneshin/components";
import {
type InboundType
-} from '@marzneshin/features/inbounds';
+} from '@marzneshin/modules/inbounds';
export const InboundCardHeader: FC<{ entity: InboundType }> = ({ entity }) => {
return (
diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx b/dashboard/src/modules/hosts/tables/inbound-hosts/index.tsx
similarity index 94%
rename from dashboard/src/features/hosts/tables/inbound-hosts/index.tsx
rename to dashboard/src/modules/hosts/tables/inbound-hosts/index.tsx
index 487fe37..96b969d 100644
--- a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx
+++ b/dashboard/src/modules/hosts/tables/inbound-hosts/index.tsx
@@ -1,15 +1,15 @@
import {
HostType,
fetchHosts
-} from '@marzneshin/features/hosts';
+} from '@marzneshin/modules/hosts';
import { useNavigate } from "@tanstack/react-router";
import { useState } from 'react';
import {
useInboundsQuery,
-} from '@marzneshin/features/inbounds';
+} from '@marzneshin/modules/inbounds';
import { SidebarEntityTable } from '@marzneshin/features/entity-table';
import { columns } from './columns';
-import { useDialog } from '@marzneshin/hooks';
+import { useDialog } from '@marzneshin/common/hooks';
import {
InboundNotSelectedAlertDialog
} from './inbound-not-selected-alert-dialog';
diff --git a/dashboard/src/features/hosts/tables/index.ts b/dashboard/src/modules/hosts/tables/index.ts
similarity index 100%
rename from dashboard/src/features/hosts/tables/index.ts
rename to dashboard/src/modules/hosts/tables/index.ts
diff --git a/dashboard/src/features/inbounds/index.ts b/dashboard/src/modules/inbounds/index.ts
similarity index 100%
rename from dashboard/src/features/inbounds/index.ts
rename to dashboard/src/modules/inbounds/index.ts
diff --git a/dashboard/src/modules/inbounds/services/inbound.query.ts b/dashboard/src/modules/inbounds/services/inbound.query.ts
new file mode 100644
index 0000000..804c280
--- /dev/null
+++ b/dashboard/src/modules/inbounds/services/inbound.query.ts
@@ -0,0 +1,17 @@
+import { HostType } from "@marzneshin/modules/hosts";
+import { useQuery } from "@tanstack/react-query";
+import { fetch } from "@marzneshin/common/utils";
+
+export async function fetchInbound({ queryKey }: { queryKey: [string, number] }): Promise<HostType> {
+ return fetch(`/inbounds/${queryKey[1]}`);
+}
+
+export const HostQueryFetchKey = "inbounds";
+
+export const useHostQuery = ({ inboundId }: { inboundId: number }) => {
+ return useQuery({
+ queryKey: [HostQueryFetchKey, inboundId],
+ queryFn: fetchInbound,
+ initialData: undefined
+ })
+}
diff --git a/dashboard/src/features/inbounds/services/inbounds.query.ts b/dashboard/src/modules/inbounds/services/inbounds.query.ts
similarity index 96%
rename from dashboard/src/features/inbounds/services/inbounds.query.ts
rename to dashboard/src/modules/inbounds/services/inbounds.query.ts
index 22db81b..7310993 100644
--- a/dashboard/src/features/inbounds/services/inbounds.query.ts
+++ b/dashboard/src/modules/inbounds/services/inbounds.query.ts
@@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import {
FetchEntityReturn,
UseEntityQueryProps,
diff --git a/dashboard/src/features/inbounds/services/index.ts b/dashboard/src/modules/inbounds/services/index.ts
similarity index 50%
rename from dashboard/src/features/inbounds/services/index.ts
rename to dashboard/src/modules/inbounds/services/index.ts
index 89aaa7a..6fa654d 100644
--- a/dashboard/src/features/inbounds/services/index.ts
+++ b/dashboard/src/modules/inbounds/services/index.ts
@@ -1 +1,2 @@
export * from './inbounds.query'
+export * from './inbound.query'
diff --git a/dashboard/src/features/inbounds/types/index.ts b/dashboard/src/modules/inbounds/types/index.ts
similarity index 62%
rename from dashboard/src/features/inbounds/types/index.ts
rename to dashboard/src/modules/inbounds/types/index.ts
index ae7ab40..a1eb884 100644
--- a/dashboard/src/features/inbounds/types/index.ts
+++ b/dashboard/src/modules/inbounds/types/index.ts
@@ -1,6 +1,14 @@
import { NodeType } from "@marzneshin/modules/nodes";
-export type ProtocolType = 'vmess' | 'vless' | 'trojan' | 'shadowsocks';
+export type ProtocolType =
+ "wireguard"
+ | "vless"
+ | "vmess"
+ | "trojan"
+ | "shadowsocks"
+ | "shadowsocks2022"
+ | "hysteria2"
+ | "tuic"
export interface InboundType {
id: number;
diff --git a/dashboard/src/modules/nodes/dialogs/mutation/index.tsx b/dashboard/src/modules/nodes/dialogs/mutation/index.tsx
index 95ffc0e..f597267 100644
--- a/dashboard/src/modules/nodes/dialogs/mutation/index.tsx
+++ b/dashboard/src/modules/nodes/dialogs/mutation/index.tsx
@@ -27,7 +27,7 @@ import {
useNodesUpdateMutation,
} from "../..";
import type { NodeType } from "../..";
-import { useMutationDialog, MutationDialogProps } from "@marzneshin/hooks";
+import { useMutationDialog, MutationDialogProps } from "@marzneshin/common/hooks";
export const MutationDialog: FC<MutationDialogProps<NodeType>> = ({
entity,
diff --git a/dashboard/src/modules/nodes/services/backend-stats.query.ts b/dashboard/src/modules/nodes/services/backend-stats.query.ts
index d4e55d6..edde0e7 100644
--- a/dashboard/src/modules/nodes/services/backend-stats.query.ts
+++ b/dashboard/src/modules/nodes/services/backend-stats.query.ts
@@ -1,35 +1,35 @@
import type { NodeType } from "@marzneshin/modules/nodes";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
type NodeBackendStatsQueryKey = [string, number, string, string];
interface NodeBackendStatsQuery {
- queryKey: NodeBackendStatsQueryKey;
+ queryKey: NodeBackendStatsQueryKey;
}
export async function fetchNodeBackendStats({
- queryKey,
+ queryKey,
}: NodeBackendStatsQuery): Promise<{
- running: boolean;
+ running: boolean;
} | null> {
- return fetch(`/nodes/${Number(queryKey[1])}/${queryKey[2]}/stats`)
- .then((stats) => stats)
- .catch(() => null);
+ return fetch(`/nodes/${Number(queryKey[1])}/${queryKey[2]}/stats`)
+ .then((stats) => stats)
+ .catch(() => null);
}
export const useBackendStatsQuery = (node: NodeType, backend: string) => {
- const queryKey: NodeBackendStatsQueryKey = [
- "nodes",
- node.id,
- backend,
- "stats",
- ];
+ const queryKey: NodeBackendStatsQueryKey = [
+ "nodes",
+ node.id,
+ backend,
+ "stats",
+ ];
- return useQuery({
- queryKey,
- queryFn: fetchNodeBackendStats,
- refetchInterval: 1000 * 5,
- initialData: null,
- });
+ return useQuery({
+ queryKey,
+ queryFn: fetchNodeBackendStats,
+ refetchInterval: 1000 * 5,
+ initialData: null,
+ });
};
diff --git a/dashboard/src/modules/nodes/services/create-node.mutate.ts b/dashboard/src/modules/nodes/services/create-node.mutate.ts
index f123dd2..f66c736 100644
--- a/dashboard/src/modules/nodes/services/create-node.mutate.ts
+++ b/dashboard/src/modules/nodes/services/create-node.mutate.ts
@@ -1,6 +1,6 @@
import { NodeType, NodesQueryFetchKey } from "@marzneshin/modules/nodes";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/nodes/services/delete-node.mutate.ts b/dashboard/src/modules/nodes/services/delete-node.mutate.ts
index 714b9cd..27b636e 100644
--- a/dashboard/src/modules/nodes/services/delete-node.mutate.ts
+++ b/dashboard/src/modules/nodes/services/delete-node.mutate.ts
@@ -1,7 +1,7 @@
import { NodeType, NodesQueryFetchKey } from "@marzneshin/modules/nodes";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/nodes/services/node.query.ts b/dashboard/src/modules/nodes/services/node.query.ts
index b97c3d2..27b4ac3 100644
--- a/dashboard/src/modules/nodes/services/node.query.ts
+++ b/dashboard/src/modules/nodes/services/node.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import type { NodeType } from "../types";
export async function fetchNode({
diff --git a/dashboard/src/modules/nodes/services/nodes-usage.query.ts b/dashboard/src/modules/nodes/services/nodes-usage.query.ts
index 280feaf..dc03e59 100644
--- a/dashboard/src/modules/nodes/services/nodes-usage.query.ts
+++ b/dashboard/src/modules/nodes/services/nodes-usage.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
export type UsageMetric = number[];
diff --git a/dashboard/src/modules/nodes/services/nodes.query.ts b/dashboard/src/modules/nodes/services/nodes.query.ts
index 8759c21..cec2528 100644
--- a/dashboard/src/modules/nodes/services/nodes.query.ts
+++ b/dashboard/src/modules/nodes/services/nodes.query.ts
@@ -1,6 +1,6 @@
import type { NodeType } from "@marzneshin/modules/nodes";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import type {
EntityQueryKeyType,
UseEntityQueryProps,
diff --git a/dashboard/src/modules/nodes/services/settings.mutate.ts b/dashboard/src/modules/nodes/services/settings.mutate.ts
index afd136a..d3d5b67 100644
--- a/dashboard/src/modules/nodes/services/settings.mutate.ts
+++ b/dashboard/src/modules/nodes/services/settings.mutate.ts
@@ -1,6 +1,6 @@
import type { NodeType } from "@marzneshin/modules/nodes";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/nodes/services/settings.query.ts b/dashboard/src/modules/nodes/services/settings.query.ts
index b456362..2acd809 100644
--- a/dashboard/src/modules/nodes/services/settings.query.ts
+++ b/dashboard/src/modules/nodes/services/settings.query.ts
@@ -1,6 +1,6 @@
import type { NodeType } from "@marzneshin/modules/nodes";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
type NodesSettingsQueryKey = [string, number, string, string];
diff --git a/dashboard/src/modules/nodes/services/update-node.mutate.ts b/dashboard/src/modules/nodes/services/update-node.mutate.ts
index 772022b..1bf38db 100644
--- a/dashboard/src/modules/nodes/services/update-node.mutate.ts
+++ b/dashboard/src/modules/nodes/services/update-node.mutate.ts
@@ -1,6 +1,6 @@
import { NodeType } from "@marzneshin/modules/nodes";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import { NodesQueryFetchKey } from "./nodes.query";
diff --git a/dashboard/src/modules/nodes/tables/nodes-status-badge.tsx b/dashboard/src/modules/nodes/tables/nodes-status-badge.tsx
index 336d650..3bf8da1 100644
--- a/dashboard/src/modules/nodes/tables/nodes-status-badge.tsx
+++ b/dashboard/src/modules/nodes/tables/nodes-status-badge.tsx
@@ -1,6 +1,6 @@
import { FC } from 'react';
import { Badge, Label } from '@marzneshin/components';
-import { StatusType } from '@marzneshin/types';
+import { StatusType } from '@marzneshin/common/types';
import { NodesStatus } from '..';
interface NodesStatusBadgeProps {
diff --git a/dashboard/src/modules/nodes/types/index.ts b/dashboard/src/modules/nodes/types/index.ts
index 8b51e98..da40c4f 100644
--- a/dashboard/src/modules/nodes/types/index.ts
+++ b/dashboard/src/modules/nodes/types/index.ts
@@ -1,55 +1,55 @@
-import type { StatusType } from "@marzneshin/types/status";
+import type { StatusType } from "@marzneshin/common/types/status";
import { PowerOff, Zap, ZapOff } from "lucide-react";
import { z } from "zod";
export const NodesStatus = {
- healthy: {
- label: "healthy",
- icon: Zap,
- },
- unhealthy: {
- label: "unhealthy",
- icon: ZapOff,
- },
- disabled: {
- label: "disabled",
- icon: PowerOff,
- },
- none: {
- label: "none",
- icon: null,
- },
+ healthy: {
+ label: "healthy",
+ icon: Zap,
+ },
+ unhealthy: {
+ label: "unhealthy",
+ icon: ZapOff,
+ },
+ disabled: {
+ label: "disabled",
+ icon: PowerOff,
+ },
+ none: {
+ label: "none",
+ icon: null,
+ },
} as Record<string, StatusType>;
export const NodeSchema = z.object({
- name: z.string().min(1),
- address: z.string().min(1),
- port: z
- .number()
- .min(1)
- .or(z.string().transform((v) => Number.parseFloat(v))),
- id: z.number().nullable().optional(),
- status: z.enum([
- NodesStatus.healthy.label,
- NodesStatus.unhealthy.label,
- "none",
- NodesStatus.disabled.label,
- ]),
- usage_coefficient: z
- .number()
- .default(1.0)
- .or(z.string().transform((v) => Number.parseFloat(v))),
- connection_backend: z.enum(["grpclib", "grpcio"]).default("grpclib"),
+ name: z.string().min(1),
+ address: z.string().min(1),
+ port: z
+ .number()
+ .min(1)
+ .or(z.string().transform((v) => Number.parseFloat(v))),
+ id: z.number().nullable().optional(),
+ status: z.enum([
+ NodesStatus.healthy.label,
+ NodesStatus.unhealthy.label,
+ "none",
+ NodesStatus.disabled.label,
+ ]),
+ usage_coefficient: z
+ .number()
+ .default(1.0)
+ .or(z.string().transform((v) => Number.parseFloat(v))),
+ connection_backend: z.enum(["grpclib", "grpcio"]).default("grpclib"),
});
export type NodeBackendType = {
- name: string;
- backend_type: string;
- version: string;
- running: boolean;
+ name: string;
+ backend_type: string;
+ version: string;
+ running: boolean;
};
export type NodeType = z.infer<typeof NodeSchema> & {
- id: number;
- backends: NodeBackendType[];
+ id: number;
+ backends: NodeBackendType[];
};
diff --git a/dashboard/src/features/services/components/dialogs/delete-confirmation.dialog.tsx b/dashboard/src/modules/services/components/dialogs/delete-confirmation.dialog.tsx
similarity index 96%
rename from dashboard/src/features/services/components/dialogs/delete-confirmation.dialog.tsx
rename to dashboard/src/modules/services/components/dialogs/delete-confirmation.dialog.tsx
index a946c29..d7569ed 100644
--- a/dashboard/src/features/services/components/dialogs/delete-confirmation.dialog.tsx
+++ b/dashboard/src/modules/services/components/dialogs/delete-confirmation.dialog.tsx
@@ -1,7 +1,7 @@
import { DeleteConfirmation } from '@marzneshin/components'
import { type FC, useEffect } from 'react'
-import { ServiceType, useServicesDeletionMutation } from '@marzneshin/features/services'
+import { ServiceType, useServicesDeletionMutation } from '@marzneshin/modules/services'
interface ServicesDeleteConfirmationDialogProps {
onOpenChange: (state: boolean) => void
diff --git a/dashboard/src/features/services/components/dialogs/index.ts b/dashboard/src/modules/services/components/dialogs/index.ts
similarity index 100%
rename from dashboard/src/features/services/components/dialogs/index.ts
rename to dashboard/src/modules/services/components/dialogs/index.ts
diff --git a/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx b/dashboard/src/modules/services/components/dialogs/mutation/fields/inbounds.tsx
similarity index 97%
rename from dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx
rename to dashboard/src/modules/services/components/dialogs/mutation/fields/inbounds.tsx
index def8cd1..7ec5e0b 100644
--- a/dashboard/src/features/services/components/dialogs/mutation/fields/inbounds.tsx
+++ b/dashboard/src/modules/services/components/dialogs/mutation/fields/inbounds.tsx
@@ -11,14 +11,14 @@ import {
import {
useInboundsQuery,
type InboundType,
-} from "@marzneshin/features/inbounds";
+} from "@marzneshin/modules/inbounds";
import {
useFormContext,
type FieldValues,
type ControllerRenderProps,
} from "react-hook-form";
import { useTranslation } from "react-i18next";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { Box, GlobeLock } from "lucide-react";
export const InboundCard = ({
diff --git a/dashboard/src/features/services/components/dialogs/mutation/fields/index.ts b/dashboard/src/modules/services/components/dialogs/mutation/fields/index.ts
similarity index 100%
rename from dashboard/src/features/services/components/dialogs/mutation/fields/index.ts
rename to dashboard/src/modules/services/components/dialogs/mutation/fields/index.ts
diff --git a/dashboard/src/features/services/components/dialogs/mutation/fields/name.tsx b/dashboard/src/modules/services/components/dialogs/mutation/fields/name.tsx
similarity index 100%
rename from dashboard/src/features/services/components/dialogs/mutation/fields/name.tsx
rename to dashboard/src/modules/services/components/dialogs/mutation/fields/name.tsx
diff --git a/dashboard/src/features/services/components/dialogs/mutation/index.tsx b/dashboard/src/modules/services/components/dialogs/mutation/index.tsx
similarity index 97%
rename from dashboard/src/features/services/components/dialogs/mutation/index.tsx
rename to dashboard/src/modules/services/components/dialogs/mutation/index.tsx
index 634d5d1..a6e1672 100644
--- a/dashboard/src/features/services/components/dialogs/mutation/index.tsx
+++ b/dashboard/src/modules/services/components/dialogs/mutation/index.tsx
@@ -11,10 +11,10 @@ import {
type ServiceType,
useServicesCreationMutation,
useServicesUpdateMutation,
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
import { useTranslation } from "react-i18next";
import { z } from "zod";
-import { useMutationDialog, MutationDialogProps } from "@marzneshin/hooks";
+import { useMutationDialog, MutationDialogProps } from "@marzneshin/common/hooks";
import { NameField, InboundsField } from "./fields";
export const ServiceSchema = z.object({
diff --git a/dashboard/src/features/services/components/dialogs/settings.dialog.tsx b/dashboard/src/modules/services/components/dialogs/settings.dialog.tsx
similarity index 97%
rename from dashboard/src/features/services/components/dialogs/settings.dialog.tsx
rename to dashboard/src/modules/services/components/dialogs/settings.dialog.tsx
index adaa77c..cb62bfe 100644
--- a/dashboard/src/features/services/components/dialogs/settings.dialog.tsx
+++ b/dashboard/src/modules/services/components/dialogs/settings.dialog.tsx
@@ -12,7 +12,7 @@ import {
ServicesUsersTable,
ServiceInboundsTable,
ServiceType,
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
interface ServicecSettingsDialogProps extends SettingsDialogProps {
entity: ServiceType;
diff --git a/dashboard/src/features/services/components/form-fields/index.ts b/dashboard/src/modules/services/components/form-fields/index.ts
similarity index 100%
rename from dashboard/src/features/services/components/form-fields/index.ts
rename to dashboard/src/modules/services/components/form-fields/index.ts
diff --git a/dashboard/src/features/services/components/form-fields/services.tsx b/dashboard/src/modules/services/components/form-fields/services.tsx
similarity index 97%
rename from dashboard/src/features/services/components/form-fields/services.tsx
rename to dashboard/src/modules/services/components/form-fields/services.tsx
index 7f6acbe..6aa8b23 100644
--- a/dashboard/src/features/services/components/form-fields/services.tsx
+++ b/dashboard/src/modules/services/components/form-fields/services.tsx
@@ -17,9 +17,9 @@ import { ExclamationTriangleIcon } from '@radix-ui/react-icons';
import {
useServicesQuery,
type ServiceType,
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
import { ServiceCard } from "@marzneshin/modules/users";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import type { FC } from "react";
import {
useFormContext,
diff --git a/dashboard/src/features/services/components/index.ts b/dashboard/src/modules/services/components/index.ts
similarity index 100%
rename from dashboard/src/features/services/components/index.ts
rename to dashboard/src/modules/services/components/index.ts
diff --git a/dashboard/src/features/services/components/tables/inbounds/columns.tsx b/dashboard/src/modules/services/components/tables/inbounds/columns.tsx
similarity index 96%
rename from dashboard/src/features/services/components/tables/inbounds/columns.tsx
rename to dashboard/src/modules/services/components/tables/inbounds/columns.tsx
index c832a78..ed64997 100644
--- a/dashboard/src/features/services/components/tables/inbounds/columns.tsx
+++ b/dashboard/src/modules/services/components/tables/inbounds/columns.tsx
@@ -1,6 +1,6 @@
import { ColumnDef } from "@tanstack/react-table"
-import { InboundType } from "@marzneshin/features/inbounds"
+import { InboundType } from "@marzneshin/modules/inbounds"
import {
DataTableColumnHeader
} from "@marzneshin/features/entity-table"
diff --git a/dashboard/src/features/services/components/tables/inbounds/index.tsx b/dashboard/src/modules/services/components/tables/inbounds/index.tsx
similarity index 96%
rename from dashboard/src/features/services/components/tables/inbounds/index.tsx
rename to dashboard/src/modules/services/components/tables/inbounds/index.tsx
index 8f27c11..6e9cb64 100644
--- a/dashboard/src/features/services/components/tables/inbounds/index.tsx
+++ b/dashboard/src/modules/services/components/tables/inbounds/index.tsx
@@ -2,7 +2,7 @@ import { type FC, useCallback, useState } from "react";
import { Button } from "@marzneshin/components";
import { SelectableEntityTable, useRowSelection } from "@marzneshin/features/entity-table";
import { columns } from "./columns";
-import { type ServiceType, useServicesUpdateMutation, fetchSelectableServiceInbounds } from "@marzneshin/features/services";
+import { type ServiceType, useServicesUpdateMutation, fetchSelectableServiceInbounds } from "@marzneshin/modules/services";
import { useTranslation } from "react-i18next";
interface ServiceInboundsTableProps {
diff --git a/dashboard/src/features/services/components/tables/index.ts b/dashboard/src/modules/services/components/tables/index.ts
similarity index 100%
rename from dashboard/src/features/services/components/tables/index.ts
rename to dashboard/src/modules/services/components/tables/index.ts
diff --git a/dashboard/src/features/services/components/tables/services/columns.tsx b/dashboard/src/modules/services/components/tables/services/columns.tsx
similarity index 95%
rename from dashboard/src/features/services/components/tables/services/columns.tsx
rename to dashboard/src/modules/services/components/tables/services/columns.tsx
index d16f9a1..95b52cf 100644
--- a/dashboard/src/features/services/components/tables/services/columns.tsx
+++ b/dashboard/src/modules/services/components/tables/services/columns.tsx
@@ -1,5 +1,5 @@
import { ColumnDef } from "@tanstack/react-table";
-import { ServiceType } from "@marzneshin/features/services";
+import { ServiceType } from "@marzneshin/modules/services";
import {
DataTableActionsCell,
DataTableColumnHeader
diff --git a/dashboard/src/features/services/components/tables/services/index.tsx b/dashboard/src/modules/services/components/tables/services/index.tsx
similarity index 96%
rename from dashboard/src/features/services/components/tables/services/index.tsx
rename to dashboard/src/modules/services/components/tables/services/index.tsx
index a61073e..a1f392b 100644
--- a/dashboard/src/features/services/components/tables/services/index.tsx
+++ b/dashboard/src/modules/services/components/tables/services/index.tsx
@@ -3,7 +3,7 @@ import {
ServicesQueryFetchKey,
fetchServices,
ServiceType
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
import { columns as columnsFn } from "./columns";
import { EntityTable } from "@marzneshin/features/entity-table";
import { useNavigate } from "@tanstack/react-router";
diff --git a/dashboard/src/features/services/components/tables/users/columns.tsx b/dashboard/src/modules/services/components/tables/users/columns.tsx
similarity index 100%
rename from dashboard/src/features/services/components/tables/users/columns.tsx
rename to dashboard/src/modules/services/components/tables/users/columns.tsx
diff --git a/dashboard/src/features/services/components/tables/users/index.tsx b/dashboard/src/modules/services/components/tables/users/index.tsx
similarity index 96%
rename from dashboard/src/features/services/components/tables/users/index.tsx
rename to dashboard/src/modules/services/components/tables/users/index.tsx
index 324bdad..97c6cd7 100644
--- a/dashboard/src/features/services/components/tables/users/index.tsx
+++ b/dashboard/src/modules/services/components/tables/users/index.tsx
@@ -2,7 +2,7 @@
import { FC } from "react";
import { DoubleEntityTable } from "@marzneshin/features/entity-table";
import { columns } from "./columns";
-import { fetchServiceUsers, type ServiceType } from "@marzneshin/features/services";
+import { fetchServiceUsers, type ServiceType } from "@marzneshin/modules/services";
interface ServicesUsersTableProps {
service: ServiceType
diff --git a/dashboard/src/features/services/contexts/index.ts b/dashboard/src/modules/services/contexts/index.ts
similarity index 100%
rename from dashboard/src/features/services/contexts/index.ts
rename to dashboard/src/modules/services/contexts/index.ts
diff --git a/dashboard/src/features/services/contexts/router-context.ts b/dashboard/src/modules/services/contexts/router-context.ts
similarity index 84%
rename from dashboard/src/features/services/contexts/router-context.ts
rename to dashboard/src/modules/services/contexts/router-context.ts
index 99b8c16..b172571 100644
--- a/dashboard/src/features/services/contexts/router-context.ts
+++ b/dashboard/src/modules/services/contexts/router-context.ts
@@ -1,5 +1,5 @@
import { createContext, useContext } from "react";
-import { ServiceType } from "@marzneshin/features/services";
+import { ServiceType } from "@marzneshin/modules/services";
interface RouterServiceContextProps {
service: ServiceType;
diff --git a/dashboard/src/features/services/index.ts b/dashboard/src/modules/services/index.ts
similarity index 100%
rename from dashboard/src/features/services/index.ts
rename to dashboard/src/modules/services/index.ts
diff --git a/dashboard/src/features/services/services/create-service.mutate.ts b/dashboard/src/modules/services/services/create-service.mutate.ts
similarity index 93%
rename from dashboard/src/features/services/services/create-service.mutate.ts
rename to dashboard/src/modules/services/services/create-service.mutate.ts
index 33ea320..4ba592d 100644
--- a/dashboard/src/features/services/services/create-service.mutate.ts
+++ b/dashboard/src/modules/services/services/create-service.mutate.ts
@@ -1,6 +1,6 @@
-import { ServiceMutationType, ServicesQueryFetchKey } from "@marzneshin/features/services";
+import { ServiceMutationType, ServicesQueryFetchKey } from "@marzneshin/modules/services";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/features/services/services/delete-service.mutate.ts b/dashboard/src/modules/services/services/delete-service.mutate.ts
similarity index 93%
rename from dashboard/src/features/services/services/delete-service.mutate.ts
rename to dashboard/src/modules/services/services/delete-service.mutate.ts
index d26f7e7..de7ce2c 100644
--- a/dashboard/src/features/services/services/delete-service.mutate.ts
+++ b/dashboard/src/modules/services/services/delete-service.mutate.ts
@@ -1,6 +1,6 @@
-import { ServiceType, ServicesQueryFetchKey } from "@marzneshin/features/services";
+import { ServiceType, ServicesQueryFetchKey } from "@marzneshin/modules/services";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/features/services/services/index.ts b/dashboard/src/modules/services/services/index.ts
similarity index 100%
rename from dashboard/src/features/services/services/index.ts
rename to dashboard/src/modules/services/services/index.ts
diff --git a/dashboard/src/features/services/services/service-inbounds.query.ts b/dashboard/src/modules/services/services/service-inbounds.query.ts
similarity index 93%
rename from dashboard/src/features/services/services/service-inbounds.query.ts
rename to dashboard/src/modules/services/services/service-inbounds.query.ts
index 2409f01..8dc63c4 100644
--- a/dashboard/src/features/services/services/service-inbounds.query.ts
+++ b/dashboard/src/modules/services/services/service-inbounds.query.ts
@@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
-import { InboundType } from "@marzneshin/features/inbounds";
+import { fetch } from "@marzneshin/common/utils";
+import { InboundType } from "@marzneshin/modules/inbounds";
import {
FetchEntityReturn,
SelectableEntityQueryKeyType
diff --git a/dashboard/src/features/services/services/service-users.query.ts b/dashboard/src/modules/services/services/service-users.query.ts
similarity index 95%
rename from dashboard/src/features/services/services/service-users.query.ts
rename to dashboard/src/modules/services/services/service-users.query.ts
index a0bb6c2..dad4566 100644
--- a/dashboard/src/features/services/services/service-users.query.ts
+++ b/dashboard/src/modules/services/services/service-users.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { UserType } from "@marzneshin/modules/users";
import type {
DoubleEntityQueryKeyType,
diff --git a/dashboard/src/features/services/services/service.query.ts b/dashboard/src/modules/services/services/service.query.ts
similarity index 93%
rename from dashboard/src/features/services/services/service.query.ts
rename to dashboard/src/modules/services/services/service.query.ts
index 166847e..077c2cc 100644
--- a/dashboard/src/features/services/services/service.query.ts
+++ b/dashboard/src/modules/services/services/service.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import type { ServiceType } from "../types";
export async function fetchService({
diff --git a/dashboard/src/features/services/services/services.query.ts b/dashboard/src/modules/services/services/services.query.ts
similarity index 97%
rename from dashboard/src/features/services/services/services.query.ts
rename to dashboard/src/modules/services/services/services.query.ts
index 82cb479..845953d 100644
--- a/dashboard/src/features/services/services/services.query.ts
+++ b/dashboard/src/modules/services/services/services.query.ts
@@ -1,4 +1,4 @@
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { ServiceType } from "../types";
import {
EntityQueryKeyType,
diff --git a/dashboard/src/features/services/services/update-service.mutate.ts b/dashboard/src/modules/services/services/update-service.mutate.ts
similarity index 95%
rename from dashboard/src/features/services/services/update-service.mutate.ts
rename to dashboard/src/modules/services/services/update-service.mutate.ts
index 89beb66..b740659 100644
--- a/dashboard/src/features/services/services/update-service.mutate.ts
+++ b/dashboard/src/modules/services/services/update-service.mutate.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import { ServicesQueryFetchKey } from "./services.query";
diff --git a/dashboard/src/features/services/types/index.ts b/dashboard/src/modules/services/types/index.ts
similarity index 100%
rename from dashboard/src/features/services/types/index.ts
rename to dashboard/src/modules/services/types/index.ts
diff --git a/dashboard/src/features/services/types/services-mutation.type.ts b/dashboard/src/modules/services/types/services-mutation.type.ts
similarity index 100%
rename from dashboard/src/features/services/types/services-mutation.type.ts
rename to dashboard/src/modules/services/types/services-mutation.type.ts
diff --git a/dashboard/src/features/services/types/services.type.ts b/dashboard/src/modules/services/types/services.type.ts
similarity index 100%
rename from dashboard/src/features/services/types/services.type.ts
rename to dashboard/src/modules/services/types/services.type.ts
diff --git a/dashboard/src/features/settings/certificate-button/index.tsx b/dashboard/src/modules/settings/certificate-button/index.tsx
similarity index 100%
rename from dashboard/src/features/settings/certificate-button/index.tsx
rename to dashboard/src/modules/settings/certificate-button/index.tsx
diff --git a/dashboard/src/features/settings/index.ts b/dashboard/src/modules/settings/index.ts
similarity index 100%
rename from dashboard/src/features/settings/index.ts
rename to dashboard/src/modules/settings/index.ts
diff --git a/dashboard/src/features/settings/services/certificate.query.ts b/dashboard/src/modules/settings/services/certificate.query.ts
similarity index 91%
rename from dashboard/src/features/settings/services/certificate.query.ts
rename to dashboard/src/modules/settings/services/certificate.query.ts
index 69d3e1f..1513c68 100644
--- a/dashboard/src/features/settings/services/certificate.query.ts
+++ b/dashboard/src/modules/settings/services/certificate.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { NodesQueryFetchKey } from "@marzneshin/modules/nodes";
export async function fetchCertificate(): Promise<string> {
diff --git a/dashboard/src/features/settings/services/index.ts b/dashboard/src/modules/settings/services/index.ts
similarity index 100%
rename from dashboard/src/features/settings/services/index.ts
rename to dashboard/src/modules/settings/services/index.ts
diff --git a/dashboard/src/features/subscription-settings/form/fields/index.ts b/dashboard/src/modules/settings/subscription/form/fields/index.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/fields/index.ts
rename to dashboard/src/modules/settings/subscription/form/fields/index.ts
diff --git a/dashboard/src/features/subscription-settings/form/fields/placeholder-remark.tsx b/dashboard/src/modules/settings/subscription/form/fields/placeholder-remark.tsx
similarity index 95%
rename from dashboard/src/features/subscription-settings/form/fields/placeholder-remark.tsx
rename to dashboard/src/modules/settings/subscription/form/fields/placeholder-remark.tsx
index c2210d4..63d88bb 100644
--- a/dashboard/src/features/subscription-settings/form/fields/placeholder-remark.tsx
+++ b/dashboard/src/modules/settings/subscription/form/fields/placeholder-remark.tsx
@@ -8,7 +8,7 @@ import {
PopoverTrigger,
PopoverContent,
} from "@marzneshin/components";
-import { PopoverGuide } from "@marzneshin/features/hosts";
+import { PopoverGuide } from "@marzneshin/modules/hosts";
import { InfoIcon } from 'lucide-react';
import { useFormContext } from "react-hook-form";
import { useTranslation } from "react-i18next";
diff --git a/dashboard/src/features/subscription-settings/form/fields/profile-title.tsx b/dashboard/src/modules/settings/subscription/form/fields/profile-title.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/fields/profile-title.tsx
rename to dashboard/src/modules/settings/subscription/form/fields/profile-title.tsx
diff --git a/dashboard/src/features/subscription-settings/form/fields/support-link.tsx b/dashboard/src/modules/settings/subscription/form/fields/support-link.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/fields/support-link.tsx
rename to dashboard/src/modules/settings/subscription/form/fields/support-link.tsx
diff --git a/dashboard/src/features/subscription-settings/form/fields/update-interval.tsx b/dashboard/src/modules/settings/subscription/form/fields/update-interval.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/fields/update-interval.tsx
rename to dashboard/src/modules/settings/subscription/form/fields/update-interval.tsx
diff --git a/dashboard/src/features/subscription-settings/form/fields/url-prefix.tsx b/dashboard/src/modules/settings/subscription/form/fields/url-prefix.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/fields/url-prefix.tsx
rename to dashboard/src/modules/settings/subscription/form/fields/url-prefix.tsx
diff --git a/dashboard/src/features/subscription-settings/form/form.tsx b/dashboard/src/modules/settings/subscription/form/form.tsx
similarity index 99%
rename from dashboard/src/features/subscription-settings/form/form.tsx
rename to dashboard/src/modules/settings/subscription/form/form.tsx
index 1073652..18093b0 100644
--- a/dashboard/src/features/subscription-settings/form/form.tsx
+++ b/dashboard/src/modules/settings/subscription/form/form.tsx
@@ -26,7 +26,7 @@ import { NoRulesAlert } from "./no-rules-alert";
import {
useSubscriptionSettingsQuery,
useSubscriptionSettingsMutation,
-} from "@marzneshin/features/subscription-settings";
+} from "@marzneshin/modules/settings/subscription";
import { useEffect, useCallback } from "react";
export function SubscriptionRulesForm() {
diff --git a/dashboard/src/features/subscription-settings/form/index.ts b/dashboard/src/modules/settings/subscription/form/index.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/index.ts
rename to dashboard/src/modules/settings/subscription/form/index.ts
diff --git a/dashboard/src/features/subscription-settings/form/no-rules-alert.tsx b/dashboard/src/modules/settings/subscription/form/no-rules-alert.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/no-rules-alert.tsx
rename to dashboard/src/modules/settings/subscription/form/no-rules-alert.tsx
diff --git a/dashboard/src/features/subscription-settings/form/overlay.tsx b/dashboard/src/modules/settings/subscription/form/overlay.tsx
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/overlay.tsx
rename to dashboard/src/modules/settings/subscription/form/overlay.tsx
diff --git a/dashboard/src/features/subscription-settings/form/rule-item.tsx b/dashboard/src/modules/settings/subscription/form/rule-item.tsx
similarity index 98%
rename from dashboard/src/features/subscription-settings/form/rule-item.tsx
rename to dashboard/src/modules/settings/subscription/form/rule-item.tsx
index 379fbc3..6050c73 100644
--- a/dashboard/src/features/subscription-settings/form/rule-item.tsx
+++ b/dashboard/src/modules/settings/subscription/form/rule-item.tsx
@@ -13,7 +13,7 @@ import {
SelectValue,
DeleteConfirmation
} from "@marzneshin/components";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
import {
Schema
} from "./schema"
diff --git a/dashboard/src/features/subscription-settings/form/schema.ts b/dashboard/src/modules/settings/subscription/form/schema.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/form/schema.ts
rename to dashboard/src/modules/settings/subscription/form/schema.ts
diff --git a/dashboard/src/features/subscription-settings/index.ts b/dashboard/src/modules/settings/subscription/index.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/index.ts
rename to dashboard/src/modules/settings/subscription/index.ts
diff --git a/dashboard/src/features/subscription-settings/services/index.ts b/dashboard/src/modules/settings/subscription/services/index.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/services/index.ts
rename to dashboard/src/modules/settings/subscription/services/index.ts
diff --git a/dashboard/src/features/subscription-settings/services/subscription-settings.mutate.ts b/dashboard/src/modules/settings/subscription/services/subscription-settings.mutate.ts
similarity index 90%
rename from dashboard/src/features/subscription-settings/services/subscription-settings.mutate.ts
rename to dashboard/src/modules/settings/subscription/services/subscription-settings.mutate.ts
index 9f0bfec..88d8136 100644
--- a/dashboard/src/features/subscription-settings/services/subscription-settings.mutate.ts
+++ b/dashboard/src/modules/settings/subscription/services/subscription-settings.mutate.ts
@@ -1,12 +1,12 @@
import { NodeType } from "@marzneshin/modules/nodes";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
subscriptionSettingsQueryKey,
SubscriptionSettingsType
-} from "@marzneshin/features/subscription-settings";
+} from "@marzneshin/modules/settings/subscription";
export async function updateSubscriptionSettings(settings: SubscriptionSettingsType): Promise<NodeType> {
return fetch("/system/settings/subscription", { method: 'put', body: settings }).then((node) => {
diff --git a/dashboard/src/features/subscription-settings/services/subscription-settings.query.ts b/dashboard/src/modules/settings/subscription/services/subscription-settings.query.ts
similarity index 83%
rename from dashboard/src/features/subscription-settings/services/subscription-settings.query.ts
rename to dashboard/src/modules/settings/subscription/services/subscription-settings.query.ts
index 099c387..4f8b0ab 100644
--- a/dashboard/src/features/subscription-settings/services/subscription-settings.query.ts
+++ b/dashboard/src/modules/settings/subscription/services/subscription-settings.query.ts
@@ -1,6 +1,6 @@
-import { SubscriptionSettingsType } from "@marzneshin/features/subscription-settings";
+import { SubscriptionSettingsType } from "@marzneshin/modules/settings/subscription";
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
export async function fetchSubscriptionSettings(): Promise<SubscriptionSettingsType> {
return fetch(`/system/settings/subscription`);
diff --git a/dashboard/src/features/subscription-settings/subscription-rule.type.ts b/dashboard/src/modules/settings/subscription/subscription-rule.type.ts
similarity index 100%
rename from dashboard/src/features/subscription-settings/subscription-rule.type.ts
rename to dashboard/src/modules/settings/subscription/subscription-rule.type.ts
diff --git a/dashboard/src/features/subscription-settings/widget/index.tsx b/dashboard/src/modules/settings/subscription/widget/index.tsx
similarity index 84%
rename from dashboard/src/features/subscription-settings/widget/index.tsx
rename to dashboard/src/modules/settings/subscription/widget/index.tsx
index 6faf713..9fe76ba 100644
--- a/dashboard/src/features/subscription-settings/widget/index.tsx
+++ b/dashboard/src/modules/settings/subscription/widget/index.tsx
@@ -1,7 +1,7 @@
import {
SectionWidget
} from "@marzneshin/components";
-import { SubscriptionRulesForm } from "@marzneshin/features/subscription-settings";
+import { SubscriptionRulesForm } from "@marzneshin/modules/settings/subscription";
import { useTranslation } from "react-i18next";
export const SubscriptionSettingsWidget = () => {
diff --git a/dashboard/src/features/settings/widgets/certificate.tsx b/dashboard/src/modules/settings/widgets/certificate.tsx
similarity index 89%
rename from dashboard/src/features/settings/widgets/certificate.tsx
rename to dashboard/src/modules/settings/widgets/certificate.tsx
index 0de7124..2bbcd3c 100644
--- a/dashboard/src/features/settings/widgets/certificate.tsx
+++ b/dashboard/src/modules/settings/widgets/certificate.tsx
@@ -3,7 +3,7 @@ import {
} from "@marzneshin/components";
import {
CertificateButton
-} from "@marzneshin/features/settings";
+} from "@marzneshin/modules/settings";
import { useTranslation } from "react-i18next";
export const CertificateWidget = () => {
diff --git a/dashboard/src/features/settings/widgets/configuration.tsx b/dashboard/src/modules/settings/widgets/configuration.tsx
similarity index 100%
rename from dashboard/src/features/settings/widgets/configuration.tsx
rename to dashboard/src/modules/settings/widgets/configuration.tsx
diff --git a/dashboard/src/features/settings/widgets/index.ts b/dashboard/src/modules/settings/widgets/index.ts
similarity index 100%
rename from dashboard/src/features/settings/widgets/index.ts
rename to dashboard/src/modules/settings/widgets/index.ts
diff --git a/dashboard/src/modules/users/api/commands/create-user.command.ts b/dashboard/src/modules/users/api/commands/create-user.command.ts
index 3e84a43..398908b 100644
--- a/dashboard/src/modules/users/api/commands/create-user.command.ts
+++ b/dashboard/src/modules/users/api/commands/create-user.command.ts
@@ -1,6 +1,6 @@
import { UserMutationType, UsersQueryFetchKey } from "@marzneshin/modules/users";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/users/api/commands/delete-user.command.ts b/dashboard/src/modules/users/api/commands/delete-user.command.ts
index a1a1c82..abf247e 100644
--- a/dashboard/src/modules/users/api/commands/delete-user.command.ts
+++ b/dashboard/src/modules/users/api/commands/delete-user.command.ts
@@ -1,6 +1,6 @@
import { UserMutationType, UsersQueryFetchKey } from "@marzneshin/modules/users";
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
diff --git a/dashboard/src/modules/users/api/commands/update-user.command.ts b/dashboard/src/modules/users/api/commands/update-user.command.ts
index 9d546bd..006ef60 100644
--- a/dashboard/src/modules/users/api/commands/update-user.command.ts
+++ b/dashboard/src/modules/users/api/commands/update-user.command.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/users/api/commands/user-status.command.ts b/dashboard/src/modules/users/api/commands/user-status.command.ts
index 9f771ec..d30df81 100644
--- a/dashboard/src/modules/users/api/commands/user-status.command.ts
+++ b/dashboard/src/modules/users/api/commands/user-status.command.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/users/api/commands/user-subscription-revoke.command.ts b/dashboard/src/modules/users/api/commands/user-subscription-revoke.command.ts
index 3e6d6dc..0dc5ef2 100644
--- a/dashboard/src/modules/users/api/commands/user-subscription-revoke.command.ts
+++ b/dashboard/src/modules/users/api/commands/user-subscription-revoke.command.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/users/api/commands/user-usage-reset.command.ts b/dashboard/src/modules/users/api/commands/user-usage-reset.command.ts
index bd3ccdf..2585710 100644
--- a/dashboard/src/modules/users/api/commands/user-usage-reset.command.ts
+++ b/dashboard/src/modules/users/api/commands/user-usage-reset.command.ts
@@ -1,5 +1,5 @@
import { useMutation } from "@tanstack/react-query";
-import { fetch, queryClient } from "@marzneshin/utils";
+import { fetch, queryClient } from "@marzneshin/common/utils";
import { toast } from "sonner";
import i18n from "@marzneshin/features/i18n";
import {
diff --git a/dashboard/src/modules/users/api/queries/user-nodes-usage.query.ts b/dashboard/src/modules/users/api/queries/user-nodes-usage.query.ts
index 66361d3..9c78808 100644
--- a/dashboard/src/modules/users/api/queries/user-nodes-usage.query.ts
+++ b/dashboard/src/modules/users/api/queries/user-nodes-usage.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { UsersQueryFetchKey } from "../..";
type UsageMetric = number[];
diff --git a/dashboard/src/modules/users/api/queries/user.query.ts b/dashboard/src/modules/users/api/queries/user.query.ts
index a989cc0..63efae0 100644
--- a/dashboard/src/modules/users/api/queries/user.query.ts
+++ b/dashboard/src/modules/users/api/queries/user.query.ts
@@ -1,5 +1,5 @@
import { queryOptions, useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import type { UserType } from "@marzneshin/modules/users";
export async function fetchUser({
diff --git a/dashboard/src/modules/users/api/queries/users-stats.query.ts b/dashboard/src/modules/users/api/queries/users-stats.query.ts
index 17f5abe..76fab9e 100644
--- a/dashboard/src/modules/users/api/queries/users-stats.query.ts
+++ b/dashboard/src/modules/users/api/queries/users-stats.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { UsersQueryFetchKey } from "../..";
export interface UsersStatsResponse {
diff --git a/dashboard/src/modules/users/api/queries/users.query.ts b/dashboard/src/modules/users/api/queries/users.query.ts
index be309db..d91e692 100644
--- a/dashboard/src/modules/users/api/queries/users.query.ts
+++ b/dashboard/src/modules/users/api/queries/users.query.ts
@@ -1,5 +1,5 @@
import { useQuery } from "@tanstack/react-query";
-import { fetch } from "@marzneshin/utils";
+import { fetch } from "@marzneshin/common/utils";
import { UserType } from "@marzneshin/modules/users";
import {
FetchEntityReturn,
diff --git a/dashboard/src/modules/users/components/dialogs/mutation/index.tsx b/dashboard/src/modules/users/components/dialogs/mutation/index.tsx
index 7742b9e..2020ac4 100644
--- a/dashboard/src/modules/users/components/dialogs/mutation/index.tsx
+++ b/dashboard/src/modules/users/components/dialogs/mutation/index.tsx
@@ -19,9 +19,9 @@ import {
UsernameField,
type UserMutationType,
} from "@marzneshin/modules/users";
-import { ServicesField } from "@marzneshin/features/services";
+import { ServicesField } from "@marzneshin/modules/services";
import { NoteField } from "./fields";
-import { type MutationDialogProps, useMutationDialog } from "@marzneshin/hooks";
+import { type MutationDialogProps, useMutationDialog } from "@marzneshin/common/hooks";
import { DataLimitFields, ExpirationMethodFields } from "./sections";
export const UsersMutationDialog: FC<MutationDialogProps<UserMutationType>> = ({
diff --git a/dashboard/src/modules/users/components/dialogs/settings/user-info/qrcode.tsx b/dashboard/src/modules/users/components/dialogs/settings/user-info/qrcode.tsx
index 79b5ba2..3f80f80 100644
--- a/dashboard/src/modules/users/components/dialogs/settings/user-info/qrcode.tsx
+++ b/dashboard/src/modules/users/components/dialogs/settings/user-info/qrcode.tsx
@@ -9,7 +9,7 @@ import {
CardTitle,
} from "@marzneshin/components";
import { useTranslation } from "react-i18next";
-import { getSubscriptionLink } from "@marzneshin/utils";
+import { getSubscriptionLink } from "@marzneshin/common/utils";
export interface QRCodeProps {
entity: UserType;
diff --git a/dashboard/src/modules/users/components/dialogs/settings/user-info/subscription-actions.tsx b/dashboard/src/modules/users/components/dialogs/settings/user-info/subscription-actions.tsx
index 43e9d5a..fd8d670 100644
--- a/dashboard/src/modules/users/components/dialogs/settings/user-info/subscription-actions.tsx
+++ b/dashboard/src/modules/users/components/dialogs/settings/user-info/subscription-actions.tsx
@@ -1,6 +1,6 @@
import { Button, HStack } from "@marzneshin/components";
import { useTranslation } from "react-i18next";
-import { getSubscriptionLink } from "@marzneshin/utils";
+import { getSubscriptionLink } from "@marzneshin/common/utils";
import { useUserSubscriptionRevokeCmd } from "@marzneshin/modules/users";
import { CopyToClipboardButton } from "@marzneshin/components";
import { SquareCode } from "lucide-react";
diff --git a/dashboard/src/modules/users/components/dialogs/settings/user-info/user-status-enable-button.tsx b/dashboard/src/modules/users/components/dialogs/settings/user-info/user-status-enable-button.tsx
index 8533612..d017c0e 100644
--- a/dashboard/src/modules/users/components/dialogs/settings/user-info/user-status-enable-button.tsx
+++ b/dashboard/src/modules/users/components/dialogs/settings/user-info/user-status-enable-button.tsx
@@ -1,5 +1,5 @@
import { Button } from "@marzneshin/components";
-import { cn } from "@marzneshin/utils";
+import { cn } from "@marzneshin/common/utils";
import { UserType, useUserStatusEnable } from "@marzneshin/modules/users";
import { LoaderIcon, UserCheck, UserX } from "lucide-react";
import { FC, useCallback, useState } from "react";
diff --git a/dashboard/src/modules/users/components/no-service-alert/index.tsx b/dashboard/src/modules/users/components/no-service-alert/index.tsx
index 2e00f91..24af4a3 100644
--- a/dashboard/src/modules/users/components/no-service-alert/index.tsx
+++ b/dashboard/src/modules/users/components/no-service-alert/index.tsx
@@ -1,4 +1,4 @@
-import { useServicesQuery } from '@marzneshin/features/services';
+import { useServicesQuery } from '@marzneshin/modules/services';
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next';
import {
diff --git a/dashboard/src/modules/users/components/online-status.tsx b/dashboard/src/modules/users/components/online-status.tsx
index 181884a..1b972f3 100644
--- a/dashboard/src/modules/users/components/online-status.tsx
+++ b/dashboard/src/modules/users/components/online-status.tsx
@@ -1,6 +1,6 @@
import { FC } from "react"
import { useTranslation } from "react-i18next"
-import { cn } from "@marzneshin/utils"
+import { cn } from "@marzneshin/common/utils"
import { UserType, isUserOnline } from "@marzneshin/modules/users"
import { Tooltip, TooltipContent, TooltipTrigger } from "@marzneshin/components"
import { Circle } from "lucide-react"
diff --git a/dashboard/src/modules/users/components/services-card.tsx b/dashboard/src/modules/users/components/services-card.tsx
index 8d21b36..e74b0d8 100644
--- a/dashboard/src/modules/users/components/services-card.tsx
+++ b/dashboard/src/modules/users/components/services-card.tsx
@@ -1,5 +1,5 @@
import { EntityFieldCard } from '@marzneshin/components';
-import { ServiceType } from '@marzneshin/features/services';
+import { ServiceType } from '@marzneshin/modules/services';
import { ServerIcon, UserIcon } from 'lucide-react';
import { FC } from 'react'
diff --git a/dashboard/src/modules/users/components/tables/services/columns.tsx b/dashboard/src/modules/users/components/tables/services/columns.tsx
index 693e266..8cbfb19 100644
--- a/dashboard/src/modules/users/components/tables/services/columns.tsx
+++ b/dashboard/src/modules/users/components/tables/services/columns.tsx
@@ -4,7 +4,7 @@ import {
} from "@marzneshin/features/entity-table"
import i18n from "@marzneshin/features/i18n"
import { Checkbox } from "@marzneshin/components"
-import { ServiceType } from "@marzneshin/features/services"
+import { ServiceType } from "@marzneshin/modules/services"
export const columns: ColumnDef<ServiceType>[] = [
{
diff --git a/dashboard/src/modules/users/components/tables/services/index.tsx b/dashboard/src/modules/users/components/tables/services/index.tsx
index 699439d..8f12ec3 100644
--- a/dashboard/src/modules/users/components/tables/services/index.tsx
+++ b/dashboard/src/modules/users/components/tables/services/index.tsx
@@ -7,7 +7,7 @@ import {
useUsersUpdateMutation,
} from "@marzneshin/modules/users";
import { useTranslation } from "react-i18next";
-import { fetchUserServices } from "@marzneshin/features/services";
+import { fetchUserServices } from "@marzneshin/modules/services";
import { useState, useCallback, FC } from "react";
interface UserServicesTableProps {
diff --git a/dashboard/src/modules/users/components/tables/users/columns.tsx b/dashboard/src/modules/users/components/tables/users/columns.tsx
index de129b5..75f4055 100644
--- a/dashboard/src/modules/users/components/tables/users/columns.tsx
+++ b/dashboard/src/modules/users/components/tables/users/columns.tsx
@@ -14,7 +14,7 @@ import {
NoPropogationButton,
} from "@marzneshin/components";
import { LinkIcon } from "lucide-react";
-import { getSubscriptionLink } from "@marzneshin/utils";
+import { getSubscriptionLink } from "@marzneshin/common/utils";
import {
DataTableColumnHeader,
DataTableColumnHeaderFilterOption,
diff --git a/dashboard/src/modules/users/components/users-status.tsx b/dashboard/src/modules/users/components/users-status.tsx
index fc2b0ca..2e53253 100644
--- a/dashboard/src/modules/users/components/users-status.tsx
+++ b/dashboard/src/modules/users/components/users-status.tsx
@@ -1,6 +1,6 @@
import { FC } from 'react';
import { Badge, Label } from '@marzneshin/components';
-import { StatusType } from '@marzneshin/types';
+import { StatusType } from '@marzneshin/common/types';
import {
AlarmClock,
BrickWall,
diff --git a/dashboard/src/modules/users/components/widgets/user-nodes-usage-widget/hooks/use-chart-config.ts b/dashboard/src/modules/users/components/widgets/user-nodes-usage-widget/hooks/use-chart-config.ts
index 98a857f..73ad4d1 100644
--- a/dashboard/src/modules/users/components/widgets/user-nodes-usage-widget/hooks/use-chart-config.ts
+++ b/dashboard/src/modules/users/components/widgets/user-nodes-usage-widget/hooks/use-chart-config.ts
@@ -2,7 +2,7 @@ import {
ChartConfig,
} from "@marzneshin/components";
import { UserNodeUsagesResponse } from "@marzneshin/modules/users";
-import { interpolateColors } from "@marzneshin/utils";
+import { interpolateColors } from "@marzneshin/common/utils";
import { interpolateRdBu } from "d3";
export const useChartConfig = (nodesUsage: UserNodeUsagesResponse) => {
diff --git a/dashboard/src/routes/__root.tsx b/dashboard/src/routes/__root.tsx
index d3b5c55..14b3a2f 100644
--- a/dashboard/src/routes/__root.tsx
+++ b/dashboard/src/routes/__root.tsx
@@ -1,6 +1,6 @@
import { TooltipProvider, Loading } from '@marzneshin/components';
import { ThemeProvider } from '@marzneshin/features/theme-switch'
-import { queryClient } from '@marzneshin/utils';
+import { queryClient } from '@marzneshin/common/utils';
import { QueryClientProvider } from '@tanstack/react-query';
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { Suspense } from 'react'
diff --git a/dashboard/src/routes/_dashboard.tsx b/dashboard/src/routes/_dashboard.tsx
index c2d7fda..3c5a7a9 100644
--- a/dashboard/src/routes/_dashboard.tsx
+++ b/dashboard/src/routes/_dashboard.tsx
@@ -11,8 +11,8 @@ import {
import { useAuth } from "@marzneshin/features/auth";
import { DashboardSidebar, ToggleButton } from "@marzneshin/features/sidebar";
import { usePanelToggle } from "@marzneshin/features/sidebar/use-panel-toggle";
-import { useScreenBreakpoint } from "@marzneshin/hooks/use-screen-breakpoint";
-import { cn } from "@marzneshin/utils";
+import { useScreenBreakpoint } from "@marzneshin/common/hooks/use-screen-breakpoint";
+import { cn } from "@marzneshin/common/utils";
import { Suspense } from "react";
import {
Outlet,
diff --git a/dashboard/src/routes/_dashboard/admins/$adminId.tsx b/dashboard/src/routes/_dashboard/admins/$adminId.tsx
index 0786638..58a752a 100644
--- a/dashboard/src/routes/_dashboard/admins/$adminId.tsx
+++ b/dashboard/src/routes/_dashboard/admins/$adminId.tsx
@@ -3,7 +3,7 @@ import {
Outlet,
} from "@tanstack/react-router";
import { useSuspenseQuery } from "@tanstack/react-query";
-import { queryClient } from "@marzneshin/utils";
+import { queryClient } from "@marzneshin/common/utils";
import {
RouterAdminContext,
adminQueryOptions,
diff --git a/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx b/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx
index dfb9609..0bdab4a 100644
--- a/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx
+++ b/dashboard/src/routes/_dashboard/admins/$adminId/delete.tsx
@@ -6,7 +6,7 @@ import {
AdminsDeleteConfirmationDialog,
useRouterAdminContext,
} from "@marzneshin/modules/admins";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const AdminDelete = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx b/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx
index 30efdf7..0831442 100644
--- a/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx
+++ b/dashboard/src/routes/_dashboard/admins/$adminId/index.tsx
@@ -6,7 +6,7 @@ import {
useRouterAdminContext,
AdminsSettingsDialog,
} from "@marzneshin/modules/admins";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const AdminOpen = () => {
const [settingsDialogOpen, setSettingsDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/hosts.lazy.tsx b/dashboard/src/routes/_dashboard/hosts.lazy.tsx
index 2fbe8f0..b573edd 100644
--- a/dashboard/src/routes/_dashboard/hosts.lazy.tsx
+++ b/dashboard/src/routes/_dashboard/hosts.lazy.tsx
@@ -2,7 +2,7 @@ import {
Page,
Loading,
} from '@marzneshin/components'
-import { InboundHostsTable } from '@marzneshin/features/hosts'
+import { InboundHostsTable } from '@marzneshin/modules/hosts'
import { SudoRoute } from '@marzneshin/features/sudo-routes'
import { createFileRoute, Outlet } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
diff --git a/dashboard/src/routes/_dashboard/hosts/$hostId.tsx b/dashboard/src/routes/_dashboard/hosts/$hostId.tsx
index a2334e3..308d8f8 100644
--- a/dashboard/src/routes/_dashboard/hosts/$hostId.tsx
+++ b/dashboard/src/routes/_dashboard/hosts/$hostId.tsx
@@ -7,7 +7,7 @@ import {
import {
RouterHostContext,
fetchHost,
-} from "@marzneshin/features/hosts";
+} from "@marzneshin/modules/hosts";
import { Suspense } from "react";
import {
AlertDialog,
diff --git a/dashboard/src/routes/_dashboard/hosts/$hostId/delete.tsx b/dashboard/src/routes/_dashboard/hosts/$hostId/delete.tsx
index 31a0a5d..ad11764 100644
--- a/dashboard/src/routes/_dashboard/hosts/$hostId/delete.tsx
+++ b/dashboard/src/routes/_dashboard/hosts/$hostId/delete.tsx
@@ -5,8 +5,8 @@ import {
import {
HostsDeleteConfirmationDialog,
useRouterHostContext,
-} from "@marzneshin/features/hosts";
-import { useDialog } from "@marzneshin/hooks";
+} from "@marzneshin/modules/hosts";
+import { useDialog } from "@marzneshin/common/hooks";
const HostDelete = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/hosts/$hostId/edit.tsx b/dashboard/src/routes/_dashboard/hosts/$hostId/edit.tsx
index 6c3ba42..f73b477 100644
--- a/dashboard/src/routes/_dashboard/hosts/$hostId/edit.tsx
+++ b/dashboard/src/routes/_dashboard/hosts/$hostId/edit.tsx
@@ -5,7 +5,7 @@ import {
import {
HostsMutationDialog,
useRouterHostContext,
-} from "@marzneshin/features/hosts";
+} from "@marzneshin/modules/hosts";
const HostEdit = () => {
const value = useRouterHostContext()
@@ -14,6 +14,7 @@ const HostEdit = () => {
return value && (
<HostsMutationDialog
entity={value.host}
+ protocol={value.host.protocol}
onClose={() => navigate({ to: "/hosts" })}
/>
);
diff --git a/dashboard/src/routes/_dashboard/hosts/$hostId/index.tsx b/dashboard/src/routes/_dashboard/hosts/$hostId/index.tsx
index 17f4ef2..47d8af0 100644
--- a/dashboard/src/routes/_dashboard/hosts/$hostId/index.tsx
+++ b/dashboard/src/routes/_dashboard/hosts/$hostId/index.tsx
@@ -5,8 +5,8 @@ import {
import {
useRouterHostContext,
HostSettingsDialog,
-} from "@marzneshin/features/hosts";
-import { useDialog } from "@marzneshin/hooks";
+} from "@marzneshin/modules/hosts";
+import { useDialog } from "@marzneshin/common/hooks";
const HostOpen = () => {
const [settingsDialogOpen, setSettingsDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/hosts/$inboundId/create.tsx b/dashboard/src/routes/_dashboard/hosts/$inboundId/create.tsx
index d693723..b551f53 100644
--- a/dashboard/src/routes/_dashboard/hosts/$inboundId/create.tsx
+++ b/dashboard/src/routes/_dashboard/hosts/$inboundId/create.tsx
@@ -1,21 +1,45 @@
-import { createFileRoute, useNavigate } from "@tanstack/react-router";
-import { HostsMutationDialog } from "@marzneshin/features/hosts";
-import { AlertDialog, AlertDialogContent } from "@marzneshin/components";
+import { Suspense } from "react";
+import {
+ createFileRoute,
+ defer,
+ Await,
+ useNavigate,
+} from "@tanstack/react-router";
+import { HostsMutationDialog } from "@marzneshin/modules/hosts";
+import { fetchInbound } from "@marzneshin/modules/inbounds";
+import { Loading, AlertDialog, AlertDialogContent } from "@marzneshin/components";
const HostCreate = () => {
const { inboundId } = Route.useParams();
+ const { inbound } = Route.useLoaderData()
const navigate = useNavigate({ from: "/hosts/$inboundId/create" });
return (
- <HostsMutationDialog
- entity={null}
- inboundId={Number(inboundId)}
- onClose={() => navigate({ to: "/hosts" })}
- />
+ <Suspense fallback={<Loading />}>
+ <Await promise={inbound}>
+ {(inbound) => (
+ <HostsMutationDialog
+ entity={null}
+ protocol={inbound.protocol}
+ inboundId={Number(inboundId)}
+ onClose={() => navigate({ to: "/hosts" })}
+ />
+ )}
+ </Await>
+ </Suspense>
);
}
export const Route = createFileRoute('/_dashboard/hosts/$inboundId/create')({
+ loader: async ({ params }) => {
+ const inboundPromise = fetchInbound({
+ queryKey: ["inbounds", Number.parseInt(params.inboundId)]
+ });
+
+ return {
+ inbound: defer(inboundPromise)
+ }
+ },
errorComponent: () => (
<AlertDialog open={true}>
<AlertDialogContent>Host not found</AlertDialogContent>
diff --git a/dashboard/src/routes/_dashboard/nodes/$nodeId/delete.tsx b/dashboard/src/routes/_dashboard/nodes/$nodeId/delete.tsx
index ef2046c..a532dca 100644
--- a/dashboard/src/routes/_dashboard/nodes/$nodeId/delete.tsx
+++ b/dashboard/src/routes/_dashboard/nodes/$nodeId/delete.tsx
@@ -6,7 +6,7 @@ import {
NodesDeleteConfirmationDialog,
useRouterNodeContext,
} from "@marzneshin/modules/nodes";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const NodeDelete = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/nodes/$nodeId/index.tsx b/dashboard/src/routes/_dashboard/nodes/$nodeId/index.tsx
index dc33800..e46ef97 100644
--- a/dashboard/src/routes/_dashboard/nodes/$nodeId/index.tsx
+++ b/dashboard/src/routes/_dashboard/nodes/$nodeId/index.tsx
@@ -6,7 +6,7 @@ import {
useRouterNodeContext,
NodesSettingsDialog,
} from "@marzneshin/modules/nodes";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const NodeOpen = () => {
const [settingsDialogOpen, setSettingsDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/services.lazy.tsx b/dashboard/src/routes/_dashboard/services.lazy.tsx
index dbc2afc..cce6690 100644
--- a/dashboard/src/routes/_dashboard/services.lazy.tsx
+++ b/dashboard/src/routes/_dashboard/services.lazy.tsx
@@ -2,7 +2,7 @@ import {
Page,
Loading,
} from "@marzneshin/components";
-import { ServicesTable } from "@marzneshin/features/services";
+import { ServicesTable } from "@marzneshin/modules/services";
import { createFileRoute, Outlet } from "@tanstack/react-router";
import { type FC, Suspense } from "react";
import { useTranslation } from "react-i18next";
diff --git a/dashboard/src/routes/_dashboard/services/$serviceId.tsx b/dashboard/src/routes/_dashboard/services/$serviceId.tsx
index a9129b5..50688bb 100644
--- a/dashboard/src/routes/_dashboard/services/$serviceId.tsx
+++ b/dashboard/src/routes/_dashboard/services/$serviceId.tsx
@@ -7,7 +7,7 @@ import {
import {
RouterServiceContext,
fetchService,
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
import { Suspense } from "react";
import {
AlertDialog,
diff --git a/dashboard/src/routes/_dashboard/services/$serviceId/delete.tsx b/dashboard/src/routes/_dashboard/services/$serviceId/delete.tsx
index e5c3d54..1d88ada 100644
--- a/dashboard/src/routes/_dashboard/services/$serviceId/delete.tsx
+++ b/dashboard/src/routes/_dashboard/services/$serviceId/delete.tsx
@@ -5,8 +5,8 @@ import {
import {
ServicesDeleteConfirmationDialog,
useRouterServiceContext,
-} from "@marzneshin/features/services";
-import { useDialog } from "@marzneshin/hooks";
+} from "@marzneshin/modules/services";
+import { useDialog } from "@marzneshin/common/hooks";
const ServiceDelete = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/services/$serviceId/edit.tsx b/dashboard/src/routes/_dashboard/services/$serviceId/edit.tsx
index cb3e47b..041a325 100644
--- a/dashboard/src/routes/_dashboard/services/$serviceId/edit.tsx
+++ b/dashboard/src/routes/_dashboard/services/$serviceId/edit.tsx
@@ -5,7 +5,7 @@ import {
import {
MutationDialog,
useRouterServiceContext,
-} from "@marzneshin/features/services";
+} from "@marzneshin/modules/services";
const ServiceEdit = () => {
const value = useRouterServiceContext()
diff --git a/dashboard/src/routes/_dashboard/services/$serviceId/index.tsx b/dashboard/src/routes/_dashboard/services/$serviceId/index.tsx
index 8c618c4..bfec1e5 100644
--- a/dashboard/src/routes/_dashboard/services/$serviceId/index.tsx
+++ b/dashboard/src/routes/_dashboard/services/$serviceId/index.tsx
@@ -5,8 +5,8 @@ import {
import {
useRouterServiceContext,
ServiceSettingsDialog,
-} from "@marzneshin/features/services";
-import { useDialog } from "@marzneshin/hooks";
+} from "@marzneshin/modules/services";
+import { useDialog } from "@marzneshin/common/hooks";
const ServiceOpen = () => {
const [settingsDialogOpen, setSettingsDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/services/create.tsx b/dashboard/src/routes/_dashboard/services/create.tsx
index b74c055..51c93e1 100644
--- a/dashboard/src/routes/_dashboard/services/create.tsx
+++ b/dashboard/src/routes/_dashboard/services/create.tsx
@@ -1,5 +1,5 @@
import { createFileRoute, useNavigate } from "@tanstack/react-router";
-import { MutationDialog } from "@marzneshin/features/services";
+import { MutationDialog } from "@marzneshin/modules/services";
const ServiceCreate = () => {
const navigate = useNavigate({ from: "/services/create" });
diff --git a/dashboard/src/routes/_dashboard/settings.lazy.tsx b/dashboard/src/routes/_dashboard/settings.lazy.tsx
index 6996961..035d3fa 100644
--- a/dashboard/src/routes/_dashboard/settings.lazy.tsx
+++ b/dashboard/src/routes/_dashboard/settings.lazy.tsx
@@ -1,7 +1,7 @@
import { Page, VStack } from '@marzneshin/components'
-import { CertificateWidget } from '@marzneshin/features/settings';
-import { SubscriptionSettingsWidget } from '@marzneshin/features/subscription-settings';
+import { CertificateWidget } from '@marzneshin/modules/settings';
+import { SubscriptionSettingsWidget } from '@marzneshin/modules/settings/subscription';
import { createFileRoute } from '@tanstack/react-router';
import { useTranslation } from 'react-i18next'
import { SudoRoute } from "@marzneshin/features/sudo-routes";
diff --git a/dashboard/src/routes/_dashboard/users/$userId.tsx b/dashboard/src/routes/_dashboard/users/$userId.tsx
index 98c538b..74ff8fd 100644
--- a/dashboard/src/routes/_dashboard/users/$userId.tsx
+++ b/dashboard/src/routes/_dashboard/users/$userId.tsx
@@ -3,7 +3,7 @@ import {
Outlet,
} from "@tanstack/react-router";
import { useSuspenseQuery } from "@tanstack/react-query";
-import { queryClient } from "@marzneshin/utils";
+import { queryClient } from "@marzneshin/common/utils";
import {
RouterUserContext,
userQueryOptions,
diff --git a/dashboard/src/routes/_dashboard/users/$userId/delete.tsx b/dashboard/src/routes/_dashboard/users/$userId/delete.tsx
index 32d5d9e..b501dc0 100644
--- a/dashboard/src/routes/_dashboard/users/$userId/delete.tsx
+++ b/dashboard/src/routes/_dashboard/users/$userId/delete.tsx
@@ -6,7 +6,7 @@ import {
UsersDeleteConfirmationDialog,
useRouterUserContext,
} from "@marzneshin/modules/users";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const UserDelete = () => {
const [deleteDialogOpen, setDeleteDialogOpen] = useDialog(true);
diff --git a/dashboard/src/routes/_dashboard/users/$userId/index.tsx b/dashboard/src/routes/_dashboard/users/$userId/index.tsx
index 45142fb..9cd9dd6 100644
--- a/dashboard/src/routes/_dashboard/users/$userId/index.tsx
+++ b/dashboard/src/routes/_dashboard/users/$userId/index.tsx
@@ -6,7 +6,7 @@ import {
useRouterUserContext,
UsersSettingsDialog,
} from "@marzneshin/modules/users";
-import { useDialog } from "@marzneshin/hooks";
+import { useDialog } from "@marzneshin/common/hooks";
const UserOpen = () => {
const [settingsDialogOpen, setSettingsDialogOpen] = useDialog(true);