Skip to content

Commit

Permalink
Merge pull request #26 from Kinfe123/fix/ui_ux
Browse files Browse the repository at this point in the history
Changelogs , CLI , and UI/UX issue and minor patches
  • Loading branch information
Kinfe123 authored Jun 1, 2024
2 parents c46d4d5 + bc0e5c4 commit b079265
Show file tree
Hide file tree
Showing 25 changed files with 795 additions and 49 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,38 @@ FarmUI is client first and animation rich ui component library built on top of r


## Why tho?
- Free and Paid Beatifull and modern Website template for Porfolio , Agency , SaaS , Docs , DX tools , frameworks.....
- We give you a full flexiblity of the source code that we styled and animated with framer motion built on top of radix and shadcn and
wee will add more
- Framework agnostic for generic components
- Full block of components as copy and paste solution.
- v0
- Free and Paid Beatifull and modern Website template for Porfolio , Agency , SaaS , Docs , DX tools , frameworks as well personalized requests are also accepted [here](https://t.me/Kinfe123)




## Installation Guide

1. Install the npm package
```bash
pnpm add @kinfe123/farm-ui
```
2. Go to https://farmui.com and grab the id of the UI or component that you want

3. Adding the UI or component based on that ID
```bash
pnpm farm-ui add {id}
```
**id** - being the id of the component from farmui.com

4. Specify the directory where you want the componnt to be installed or it uses **components** dir by default.

5. Finally you get to see the component or UI block inside of **farmui** directory nested on directory you have mentioned on step 4.


**Enjoy!**






Expand Down
10 changes: 10 additions & 0 deletions apps/www/@/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}


export function formatDate(input: string | number): string {
const date = new Date(input)
return date.toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
})
}
61 changes: 61 additions & 0 deletions apps/www/app/changelog/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import ChangelogDisplay from "components/Changelog/ChangelogDisplay";
import RetroGrid from "components/ui/Grid";
import { ChevronRight } from "lucide-react";
export const metadata = {
title: "Changelog",
description: "Changes and all jazzes will dumped here",
};

const ChangeLogPage = () => {
return (
<div className="mt-[-10px] custom-screen">
<RetroGrid />

<div className="relative">
<section className="relative max-w-full mx-auto z-1">

<div className="max-w-screen-xl z-30 mx-auto px-4 py-28 gap-12 text-gray-600 md:px-8">
<div className="space-y-5 max-w-3xl px-[-40px] leading-0 lg:leading-0 mx-auto text-center">
<h1 className="text-sm text-gray-400 group font-geist mx-auto px-5 py-2 bg-gradient-to-tr from-zinc-300/5 via-gray-400/5 to-transparent border-[2px] border-white/5 rounded-3xl w-fit">
Building one at a time
<ChevronRight className="inline w-4 h-4 ml-2 group-hover:translate-x-1 duration-300" />
</h1>

<h2 className="text-4xl tracking-tighter font-geist bg-clip-text bg-[linear-gradient(180deg,_#FFF_0%,_rgba(255,_255,_255,_0.00)_202.08%)] text-transparent mx-auto md:text-5xl lg:text-7xl">
Changes , Anouncements and All the jazz {" "}
<span className="text-transparent bg-clip-text bg-gradient-to-r from-purple-300 to-orange-200">
will be dumped here.
</span>
</h2>

<p className="max-w-2xl mx-auto text-gray-300">
We will update you on our iterations.


</p>
<div className="items-center z-30 justify-center gap-x-3 space-y-3 sm:flex sm:space-y-0">
<span className="relative inline-block overflow-hidden rounded-full p-[1.5px]">
<span className="absolute inset-[-1000%] animate-[spin_2s_linear_infinite] bg-[conic-gradient(from_90deg_at_50%_50%,#E2CBFF_0%,#393BB2_50%,#E2CBFF_100%)]" />
<div className="inline-flex h-full w-full cursor-pointer items-center justify-center rounded-full bg-gray-950 text-xs font-medium text-gray-50 backdrop-blur-3xl">
<a
href="/components"
className="inline-flex rounded-full text-center group items-center w-full justify-center bg-gradient-to-tr from-zinc-300/5 via-purple-400/20 to-transparent text-white border-input border-[1px] hover:bg-transparent/90 transition-colors sm:w-auto py-4 px-10"
>
Browse components
</a>
</div>
</span>
</div>
</div>
</div>

</section>
<ChangelogDisplay />
</div>
</div>


);
};

export default ChangeLogPage;
99 changes: 99 additions & 0 deletions apps/www/components/Changelog/AnimatedTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@

// @ts-nocheck
"use client";
import Image from "next/image";
import React, { useState } from "react";
import Link from "next/link";
import {
motion,
useTransform,
AnimatePresence,
useMotionValue,
useSpring,
} from "framer-motion";

export const AnimatedTooltip = ({
items,
}: {
items: {
id: number | string;
name: string;
designation: string;
image: string;
link: string;
}[];
}) => {
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
const springConfig = { stiffness: 100, damping: 5 };
const x = useMotionValue(0); // going to set this value on mouse move
// rotate the tooltip
const rotate = useSpring(
useTransform(x, [-100, 100], [-45, 45]),
springConfig
);
// translate the tooltip
const translateX = useSpring(
useTransform(x, [-100, 100], [-50, 50]),
springConfig
);
const handleMouseMove = (event: any) => {
const halfWidth = event.target.offsetWidth / 2;
x.set(event.nativeEvent.offsetX - halfWidth); // set the x value, which is then used in transform and rotate
};

return (
<>
{items.map((item, idx) => (
<div
className="-mr-4 relative group"
key={item.name}
// @ts-ignore
onMouseEnter={() => setHoveredIndex(item.id)}
onMouseLeave={() => setHoveredIndex(null)}
>
<AnimatePresence mode="wait">
{hoveredIndex === item.id && (
<motion.div
initial={{ opacity: 0, y: 20, scale: 0.6 }}
animate={{
opacity: 1,
y: 0,
scale: 1,
transition: {
type: "spring",
stiffness: 260,
damping: 10,
},
}}
exit={{ opacity: 0, y: 20, scale: 0.6 }}
style={{
translateX: translateX,
rotate: rotate,
whiteSpace: "nowrap",
}}
className="absolute left-[-30px] top-[-50px] flex text-xs flex-col items-center justify-center rounded-md bg-neutral-950 bg-[radial-gradient(ellipse_80%_80%_at_50%_-20%,rgba(120,119,198,0.1),rgba(255,255,255,0))] z-50 shadow-xl px-4 py-2"
>
<div className="absolute inset-x-10 z-30 w-[20%] -bottom-px bg-gradient-to-r from-transparent via-emerald-500 to-transparent h-px " />
<div className="absolute left-10 w-[40%] z-30 -bottom-px bg-gradient-to-r from-transparent via-sky-500 to-transparent h-px " />
<div className="font-bold text-white relative z-30 text-base">
{item.name}
</div>
<div className="text-white text-xs">{item.designation}</div>
</motion.div>
)}
</AnimatePresence>
<Link href={item.link} target="_blank" >
<Image
onMouseMove={handleMouseMove}
height={100}
width={100}
src={item.image}
alt={item.name}
className="object-cover !m-0 !p-0 object-top rounded-full h-10 w-10 border-2 group-hover:scale-105 group-hover:z-30 border-white relative transition duration-500"
/>
</Link>
</div>
))}
</>
);
};
138 changes: 138 additions & 0 deletions apps/www/components/Changelog/ChangelogCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

import { formatDate, cn } from "@/lib/utils"
import { Mdx } from "components/MdxComponent";
import Image from 'next/image'
import { allAuthors , allChangelogs } from "contentlayer/generated";
import { AnimatedTooltip } from "./AnimatedTooltip";
import { Separator } from "@/components/ui/separator";

interface AuthorProps {
id: string;
name: string;
designation: string;
image: string;
link: string;
}


type AuthorTypeProps = {
title: string;
avatar: string;
designation: string;
twitter: string;
body: {
raw: string;
code: string;
};
_id: string;
_raw: {
sourceFilePath: string;
sourceFileName: string;
sourceFileDir: string;
contentType: string;
flattenedPath: string;
};
type: string;
slug: string;
slugAsParams: string;

}

type changelogPost = {
title: string;
date: string;
summary: string;
image: string;
kind?: string | undefined;
authors: string[];
draft: boolean | undefined;
body: {
raw: string;
code: string;
};
_id: string;
_raw: {
sourceFilePath: string;
sourceFileName: string;
sourceFileDir: string;
contentType: string;
flattenedPath: string;
};
type: string;
slug: string;
slugAsParams: string;
}

type ChangelogProps = {
item: changelogPost,
index: number
}

const ChangeLogCard = ({ index, item }: ChangelogProps) => {
const authorsLists = allChangelogs.map((a) => a.authors)[0]
// console.log('Authorlsits; ' , authorsLists)
const metaDataOfAuthor: AuthorTypeProps[] = []
for (let eachAuthor of authorsLists) {
allAuthors.map((author) => {
if (author.title === eachAuthor) {
// @ts-ignore
metaDataOfAuthor.push(author)
}
})

}
const parseData = () => {
const authorsFmt: AuthorProps[] = []
metaDataOfAuthor.map((au) => {

let user = {
id: au!._id,
designation: au!.designation,
image: au.avatar,
name: au.title,
link: au.twitter,



}
authorsFmt.push(user)
})
return authorsFmt
}
const parsedFmt = parseData()
return (
<div key={`content-${index}`} className="mb-10">
<h2 className="text-white rounded-full text-sm max-w-xl md:max-w-3xl lg:max-w-5xl px-4 py-1 mb-4">
{formatDate(item.date)} - {item.kind}
</h2>

<p className={cn("text-4xl font-geist tracking-tighter mb-1")}>
{item.title}
</p>
<p className={cn("text-md mb-4 text-gray-400/90")}>
{item.summary}
</p>

<Separator className="h-[1px] bg-white/10 mb-5" />
<div className="text-sm prose prose-sm dark:prose-invert">
{item?.image && (
<Image
src={item.image}
alt="changelog thumbnail"
height="1000"
width="1000"
className="rounded-lg mb-10 object-cover w-full"
/>
)}
<div className="h-15 mt-10 mb-2 w-full relative">
<AnimatedTooltip items={parsedFmt} />

</div>
<Mdx code={item.body.code} />
</div>
</div>
)

}

export default ChangeLogCard
30 changes: 30 additions & 0 deletions apps/www/components/Changelog/ChangelogDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Image from "next/image"
import { TracingBeam } from "./TracingBeam"
import { cn, formatDate } from "@/lib/utils"
import { allChangelogs, allAuthors } from "contentlayer/generated"
import { Mdx } from "components/MdxComponent"
import ChangeLogCard from './ChangelogCard'




const ChangelogDisplay = () => {

const authorsLists = allChangelogs.map((a) => a.authors)




return (
<TracingBeam className="h-screen bg-transparent ">

<div className="max-w-full gap-x-10 mx-auto antialiased pt-4 relative">
{allChangelogs.map((item, index) => (
<ChangeLogCard item={item} index={index} />
))}
</div>
</TracingBeam>
)
}

export default ChangelogDisplay
Loading

0 comments on commit b079265

Please # to comment.