From cb0dfdda2e2660bbef6122c3343062b433046d4b Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Wed, 7 Jan 2026 10:28:00 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20create=20popup=20signIn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/libs/shadcn/ui/button.tsx | 41 +++-- shared/libs/shadcn/ui/dialog.tsx | 155 ++++++++++++++++++ shared/libs/shadcn/ui/input.tsx | 19 +++ shared/libs/shadcn/ui/label.tsx | 24 +++ shared/libs/shadcn/ui/separator.tsx | 28 ++++ shared/widgets/navbar/components/Navbar.tsx | 2 + shared/widgets/navbar/components/SignIn.tsx | 17 +- .../signin/components/PopupWrapper.tsx | 7 + .../widgets/signin/components/SignInCard.tsx | 40 +++++ 9 files changed, 312 insertions(+), 21 deletions(-) create mode 100644 shared/libs/shadcn/ui/dialog.tsx create mode 100644 shared/libs/shadcn/ui/input.tsx create mode 100644 shared/libs/shadcn/ui/label.tsx create mode 100644 shared/libs/shadcn/ui/separator.tsx create mode 100644 shared/widgets/signin/components/PopupWrapper.tsx create mode 100644 shared/widgets/signin/components/SignInCard.tsx diff --git a/shared/libs/shadcn/ui/button.tsx b/shared/libs/shadcn/ui/button.tsx index 8b0a97c..6c0c773 100644 --- a/shared/libs/shadcn/ui/button.tsx +++ b/shared/libs/shadcn/ui/button.tsx @@ -1,29 +1,36 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" -import { Slot } from "radix-ui" +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { Slot } from "radix-ui"; -import { cn } from "@/shared/libs/shadcn/lib/utils" +import { cn } from "@/shared/libs/shadcn/lib/utils"; const buttonVariants = cva( - "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", + "cursor-pointer focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", { variants: { variant: { default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", - outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", - ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground", - destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30", + outline: + "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", + ghost: + "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground", + destructive: + "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30", link: "text-primary underline-offset-4 hover:underline", }, size: { - default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", + default: + "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", icon: "size-8", - "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", - "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", + "icon-xs": + "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", + "icon-sm": + "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", "icon-lg": "size-9", }, }, @@ -32,7 +39,7 @@ const buttonVariants = cva( size: "default", }, } -) +); function Button({ className, @@ -42,9 +49,9 @@ function Button({ ...props }: React.ComponentProps<"button"> & VariantProps & { - asChild?: boolean + asChild?: boolean; }) { - const Comp = asChild ? Slot.Root : "button" + const Comp = asChild ? Slot.Root : "button"; return ( - ) + ); } -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/shared/libs/shadcn/ui/dialog.tsx b/shared/libs/shadcn/ui/dialog.tsx new file mode 100644 index 0000000..294c80f --- /dev/null +++ b/shared/libs/shadcn/ui/dialog.tsx @@ -0,0 +1,155 @@ +"use client" + +import * as React from "react" +import { Dialog as DialogPrimitive } from "radix-ui" + +import { cn } from "@/shared/libs/shadcn/lib/utils" +import { Button } from "@/shared/libs/shadcn/ui/button" +import { XIcon } from "lucide-react" + +function Dialog({ + ...props +}: React.ComponentProps) { + return +} + +function DialogTrigger({ + ...props +}: React.ComponentProps) { + return +} + +function DialogPortal({ + ...props +}: React.ComponentProps) { + return +} + +function DialogClose({ + ...props +}: React.ComponentProps) { + return +} + +function DialogOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogContent({ + className, + children, + showCloseButton = true, + ...props +}: React.ComponentProps & { + showCloseButton?: boolean +}) { + return ( + + + + {children} + {showCloseButton && ( + + + + )} + + + ) +} + +function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function DialogFooter({ + className, + showCloseButton = false, + children, + ...props +}: React.ComponentProps<"div"> & { + showCloseButton?: boolean +}) { + return ( +
+ {children} + {showCloseButton && ( + + + + )} +
+ ) +} + +function DialogTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DialogDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogOverlay, + DialogPortal, + DialogTitle, + DialogTrigger, +} diff --git a/shared/libs/shadcn/ui/input.tsx b/shared/libs/shadcn/ui/input.tsx new file mode 100644 index 0000000..f78ada8 --- /dev/null +++ b/shared/libs/shadcn/ui/input.tsx @@ -0,0 +1,19 @@ +import * as React from "react" + +import { cn } from "@/shared/libs/shadcn/lib/utils" + +function Input({ className, type, ...props }: React.ComponentProps<"input">) { + return ( + + ) +} + +export { Input } diff --git a/shared/libs/shadcn/ui/label.tsx b/shared/libs/shadcn/ui/label.tsx new file mode 100644 index 0000000..0931e88 --- /dev/null +++ b/shared/libs/shadcn/ui/label.tsx @@ -0,0 +1,24 @@ +"use client" + +import * as React from "react" +import { Label as LabelPrimitive } from "radix-ui" + +import { cn } from "@/shared/libs/shadcn/lib/utils" + +function Label({ + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Label } diff --git a/shared/libs/shadcn/ui/separator.tsx b/shared/libs/shadcn/ui/separator.tsx new file mode 100644 index 0000000..9bd5968 --- /dev/null +++ b/shared/libs/shadcn/ui/separator.tsx @@ -0,0 +1,28 @@ +"use client" + +import * as React from "react" +import { Separator as SeparatorPrimitive } from "radix-ui" + +import { cn } from "@/shared/libs/shadcn/lib/utils" + +function Separator({ + className, + orientation = "horizontal", + decorative = true, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Separator } diff --git a/shared/widgets/navbar/components/Navbar.tsx b/shared/widgets/navbar/components/Navbar.tsx index bb314d9..6e9372a 100644 --- a/shared/widgets/navbar/components/Navbar.tsx +++ b/shared/widgets/navbar/components/Navbar.tsx @@ -2,6 +2,8 @@ import Image from "next/image"; import NavigationLink from "./NavigationLink"; import SignIn from "./SignIn"; +import { Dialog, DialogTrigger } from "@/shared/libs/shadcn/ui/dialog"; +import PopupWrapper from "../../signin/components/PopupWrapper"; const Navbar = () => { return ( diff --git a/shared/widgets/navbar/components/SignIn.tsx b/shared/widgets/navbar/components/SignIn.tsx index 2bf9992..a0330ed 100644 --- a/shared/widgets/navbar/components/SignIn.tsx +++ b/shared/widgets/navbar/components/SignIn.tsx @@ -1,13 +1,22 @@ import { Button } from "@/shared/libs/shadcn/ui/button"; +import { Dialog, DialogTrigger } from "@/shared/libs/shadcn/ui/dialog"; import { LogIn } from "lucide-react"; +import PopupWrapper from "../../signin/components/PopupWrapper"; const SignIn = () => { return (
- + +
+ + + + + +
); }; diff --git a/shared/widgets/signin/components/PopupWrapper.tsx b/shared/widgets/signin/components/PopupWrapper.tsx new file mode 100644 index 0000000..37a4381 --- /dev/null +++ b/shared/widgets/signin/components/PopupWrapper.tsx @@ -0,0 +1,7 @@ +import SignInCard from "./SignInCard"; + +const PopupWrapper = () => { + return ; +}; + +export default PopupWrapper; diff --git a/shared/widgets/signin/components/SignInCard.tsx b/shared/widgets/signin/components/SignInCard.tsx new file mode 100644 index 0000000..623ddf5 --- /dev/null +++ b/shared/widgets/signin/components/SignInCard.tsx @@ -0,0 +1,40 @@ +import { Button } from "@/shared/libs/shadcn/ui/button"; +import { + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/shared/libs/shadcn/ui/dialog"; +import { Input } from "@/shared/libs/shadcn/ui/input"; +import { Label } from "@/shared/libs/shadcn/ui/label"; +import { Separator } from "@/shared/libs/shadcn/ui/separator"; + +const SignInCard = () => { + return ( + + + Get Started + + Sign in to access personalized features and stay updated with the + latest content. + + +
+
+ + +
+
+ + + + + + +
+ ); +}; + +export default SignInCard;