Skip to content

Commit

Permalink
Merge pull request #35 from Kinfe123/feat/code_preview
Browse files Browse the repository at this point in the history
Feat/code preview
  • Loading branch information
Kinfe123 authored Jun 5, 2024
2 parents 62f00b3 + a272c2a commit cacf5d6
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 118 deletions.
32 changes: 31 additions & 1 deletion apps/api/constants/components.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"id": "farmui-form-01",
"id": "farmui-form-01-test",
"name": "FUIForms",
"dependencies": ["lucide-react"],
"files": [
Expand All @@ -16,9 +16,39 @@
}
}
],
"tailwind": {
"animation": {
"content": [
"something: something needs to be animated",
"somewhat: somewhat neeeds to be animated"
]
},
"keyframes": {
"content": ["something: some keyframe values"]
}
},
"depends_on": ["bb87ffac-1579-4670-80be-7c1180404b4e"],
"type": "ui"
},
{
"id": "farmui-form-01",
"name": "FUIForms",
"dependencies": ["lucide-react"],
"files": [
{
"root": {
"name": "FUIForm",
"contents": {
"react": {
"code_for": "react",
"content": "\n\"use client\";\n\nimport {\n CardTitle,\n CardDescription,\n CardHeader,\n CardContent,\n CardFooter,\n Card,\n} from \"@/components/ui/card\";\nimport { Label } from \"@/components/ui/label\";\nimport { Input } from \"@/components/ui/input\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { ChevronRight, Loader2 } from \"lucide-react\";\nimport { useState, useTransition } from \"react\";\nimport { useToast } from \"@/components/ui/use-toast\";\n// raplace it with your actions.\nimport { saySomething } from \"actions/emailSubRelated\";\nimport {Button} from \"@/components/ui/button\";\ntype FormType = {\n firstName: string;\n lastName?: string;\n email: string;\n message: string;\n};\nexport default function FUIForm() {\n const [pending, startTransition] = useTransition();\n const { toast } = useToast()\n\n const [forms, setForms] = useState({\n firstName: \"\",\n lastName: \"\",\n email: \"\",\n message: \"\",\n });\n \n const handleChange = (e: any) => {\n setForms({ ...forms, [e.target.name]: e.target.value });\n };\n const onSubmit = (e:any) => {\n e.preventDefault();\n startTransition(async () => {\n saySomething({\n firstName: forms.firstName,\n lastName: forms.lastName,\n email: forms.email,\n message: forms.message,\n })\n .then((res) => {\n toast({\n position: \"bottom-left\",\n title: \"Message submitted\",\n description:\n \"You have successfully submitted your message. we will keep in touch with you with the speed of light :)\",\n });\n setForms({\n firstName:\"\",\n lastName:\"\",\n email: \"\",\n message: \"\"\n })\n })\n .catch((err) => {\n toast({\n position: \"bottom-left\",\n\n title: \"Something went wrong\",\n description:\n \"There is an error while submitting the form, Please try again later :(\",\n variant: \"destructive\",\n\n });\n });\n });\n };\n return (\n <section className=\"custom-screen-lg mx-auto z-20\">\n <div className=\"relative backdrop-blur-3xl z-10 max-w-4xl mx-auto space-y-4\">\n <Card className=\"relative mt-20 py-10 z-20 backdrop-blur-3xl\">\n <CardHeader>\n <CardDescription>\n Fill out the form below and we'll get back to you as soon as\n possible.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"\"></div>\n <form className=\"space-y-4 z-20\" onSubmit={onSubmit}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 z-20\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"first-name\">First Name</Label>\n <Input\n\n value={forms.firstName}\n onChange={(e) => handleChange(e)}\n name=\"firstName\"\n placeholder=\"Enter your first name\"\n required\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"last-name\">Last Name</Label>\n <Input\n value={forms.lastName}\n onChange={handleChange}\n name=\"lastName\"\n placeholder=\"Enter your last name\"\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n\n value={forms.email}\n name=\"email\"\n onChange={handleChange}\n placeholder=\"Enter your email\"\n type=\"email\"\n required\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"message\">Message</Label>\n <Textarea\n required\n value={forms.message}\n \n className=\"bg-transparent\"\n onChange={handleChange}\n name=\"message\"\n maxLength={200}\n \n placeholder=\"Enter your message\"\n />\n </div>\n <Button\n disabled={pending}\n variant=\"default\"\n className=\"inline-flex rounded-3xl text-center group items-center w-full justify-center bg-gradient-to-tr from-black/90 via-zinc-800 to-black border-input border-[1px] hover:bg-transparent/10 transition-colors sm:w-auto py-6 px-10\"\n >\n Submit\n {pending ? (\n <Loader2 className=\"animate-spin ml-3 w-4 h-4 flex items-center\" />\n ) : (\n <ChevronRight className=\"w-4 h-4 ml-2 group-hover:translate-x-1 duration-300\" />\n )}\n </Button>\n </form>\n </CardContent>\n </Card>\n </div>\n </section>\n );\n}\n\n\n"
}
}
}
}
],
"type": "ui"
},
{
"id": "farmui-hero-01",
"name": "FUIHeroLogoCompany",
Expand Down
18 changes: 4 additions & 14 deletions apps/www/app/components/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import SupportedLibraries from "components/ui/SupportedLibraries";
import metatag from "metatag";
import { Mdx } from "components/MdxComponent";
import { allComponents } from "contentlayer/generated";
const {ogImage} = metatag
const { ogImage } = metatag;
const title = "FarmUI - Introduction";
const description =
"Beautiful and responsive UI components and templates for React and Vue with Tailwind CSS.";
Expand Down Expand Up @@ -36,24 +36,14 @@ export const metadata = {
};

export default async () => {
const nativeComponnts = allComponents
const introDocs = allComponents.find((comp) => comp.slug === '/nativeComponents/intro')

const markdownWithMeta = fs.readFileSync(
path.join(process.cwd(), "content/intro.mdx"),
"utf-8"
const introDocs = allComponents.find(
(comp) => comp.slug === "/nativeComponents/intro"
);
const { data: frontMatter, content } = matter(markdownWithMeta);
const mdxSource = await serialize(content);

return (
<>
<article className="prose prose-invert max-w-7xl">
<Mdx code={introDocs?.body.code ?? ""}/>
{/* <MDXRemoteClient
mdxSource={{ ...mdxSource }}
components={{ SupportedLibraries }}
/> */}
<Mdx code={introDocs?.body.code ?? ""} />
</article>
</>
);
Expand Down
169 changes: 86 additions & 83 deletions apps/www/components/farmui/CopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,92 +1,95 @@
'use client'
"use client";

import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Button, ButtonProps } from "@/components/ui/button"
import { CheckIcon, ClipboardIcon , } from "lucide-react"
import React from "react"
import { cn } from "@/lib/utils"
import { CommandList } from "cmdk"
import { Separator } from "@/components/ui/separator"

DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Button, ButtonProps } from "@/components/ui/button";
import { CheckIcon, ClipboardIcon } from "lucide-react";
import React from "react";
import { cn } from "@/lib/utils";
import { CommandList } from "cmdk";
import { Separator } from "@/components/ui/separator";
import { TrackClick } from "@loglib/tracker/react";

interface CopyButtonProps extends ButtonProps {
value: string
src?: string
}
value: string;
src?: string;
}

function copyToClipboardWithMeta(value: string) {
navigator.clipboard.writeText(value);
}
export function CopyNpmCommandButton({
commands,
className,
}: {
commands: string;
className?: string;
}) {
const [hasCopied, setHasCopied] = React.useState(false);

function copyToClipboardWithMeta(value: string,) {
navigator.clipboard.writeText(value)
}
export function CopyNpmCommandButton({commands , className} : {commands: string , className?:string}) {
const [hasCopied, setHasCopied] = React.useState(false)

React.useEffect(() => {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}, [hasCopied])

const copyCommand = React.useCallback(
(value: string, pm: "npm" | "pnpm" | "yarn" | "bun") => {
copyToClipboardWithMeta(pm + " " + value)
setHasCopied(true)
},
[]
)

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
variant="ghost"
className={cn(
"relative z-20 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50",
className
)}
>
{hasCopied ? (
<CheckIcon className="h-4 w-4 mx-auto" />
) : (
<ClipboardIcon className="h-4 w-4 mx-auto" />
)}
<span className="sr-only">Copy</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="z-20 bg-black/80">
<DropdownMenuItem
onClick={() => copyCommand(commands, "npm")}
>
React.useEffect(() => {
setTimeout(() => {
setHasCopied(false);
}, 2000);
}, [hasCopied]);

npm
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10"/>
<DropdownMenuItem
onClick={() => copyCommand(commands, "yarn")}
>
yarn
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10"/>
const copyCommand = React.useCallback(
(value: string, pm: "npm" | "pnpm" | "yarn" | "bun") => {
copyToClipboardWithMeta(pm + " " + value);
setHasCopied(true);
},
[]
);

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
variant="ghost"
className={cn(
"relative z-20 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50",
className
)}
>
{hasCopied ? (
<CheckIcon className="h-4 w-4 mx-auto" />
) : (
<TrackClick
name="Installing components"
payload={{
click: "command copied",
}}
>
<ClipboardIcon className="h-4 w-4 mx-auto" />
</TrackClick>
)}
<span className="sr-only">Copy</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="z-20 bg-black/80">
<DropdownMenuItem onClick={() => copyCommand(commands, "npm")}>
npm
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10" />
<DropdownMenuItem onClick={() => copyCommand(commands, "yarn")}>
yarn
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10" />

<DropdownMenuItem
onClick={() => copyCommand(commands, "pnpm")}
>
pnpm
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10"/>
<DropdownMenuItem onClick={() => copyCommand(commands, "pnpm")}>
pnpm
</DropdownMenuItem>
<Separator className="border-[1px] border-white/10" />

<DropdownMenuItem
onClick={() => copyCommand(commands, "bun")}
>
bun
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
<DropdownMenuItem onClick={() => copyCommand(commands, "bun")}>
bun
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
3 changes: 1 addition & 2 deletions apps/www/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

import defaultTheme from "tailwindcss/defaultTheme"


import {} from "tailwindcss/types/config"
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
Expand Down
Loading

0 comments on commit cacf5d6

Please sign in to comment.