From 66cf9632b404707a02b0a567c863adb6ce35ac19 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Thu, 2 Nov 2023 03:02:52 +0000 Subject: [PATCH 01/15] setup default ui build --- frontend/nextjs/components.json | 16 +++ frontend/nextjs/package.json | 6 + frontend/nextjs/src/app/globals.css | 89 ++++++++++---- frontend/nextjs/src/app/page.tsx | 115 ++----------------- frontend/nextjs/src/components/ui/button.tsx | 56 +++++++++ frontend/nextjs/src/lib/utils.ts | 6 + frontend/nextjs/tailwind.config.ts | 66 ++++++++++- 7 files changed, 225 insertions(+), 129 deletions(-) create mode 100644 frontend/nextjs/components.json create mode 100644 frontend/nextjs/src/components/ui/button.tsx create mode 100644 frontend/nextjs/src/lib/utils.ts diff --git a/frontend/nextjs/components.json b/frontend/nextjs/components.json new file mode 100644 index 0000000..e4e8e1a --- /dev/null +++ b/frontend/nextjs/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} \ No newline at end of file diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index b5d84fd..609956b 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -9,11 +9,17 @@ "lint": "next lint" }, "dependencies": { + "@radix-ui/react-slot": "^1.0.2", "@rainbow-me/rainbowkit": "^1.1.4", + "class-variance-authority": "^0.7.0", + "clsx": "^2.0.0", + "lucide-react": "^0.291.0", "next": "14.0.1", "prettier": "^3.0.3", "react": "^18", "react-dom": "^18", + "tailwind-merge": "^2.0.0", + "tailwindcss-animate": "^1.0.7", "viem": "^1.18.1", "wagmi": "^1.4.5" }, diff --git a/frontend/nextjs/src/app/globals.css b/frontend/nextjs/src/app/globals.css index fd81e88..6a75725 100644 --- a/frontend/nextjs/src/app/globals.css +++ b/frontend/nextjs/src/app/globals.css @@ -1,27 +1,76 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; -:root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; } } - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/frontend/nextjs/src/app/page.tsx b/frontend/nextjs/src/app/page.tsx index e38c626..582d229 100644 --- a/frontend/nextjs/src/app/page.tsx +++ b/frontend/nextjs/src/app/page.tsx @@ -1,113 +1,12 @@ -import Image from 'next/image' - +import { Button } from "@/components/ui/button" export default function Home() { return ( -
-
-

- Get started by editing  - src/app/page.tsx -

-
- - By{' '} - Vercel Logo - -
-
- -
- Next.js Logo -
- -
- -

- Docs{' '} - - -> - -

-

- Find in-depth information about Next.js features and API. -

-
- - -

- Learn{' '} - - -> - -

-

- Learn about Next.js in an interactive course with quizzes! -

-
- - -

- Templates{' '} - - -> - -

-

- Explore the Next.js 13 playground. -

-
- - -

- Deploy{' '} - - -> - -

-

- Instantly deploy your Next.js site to a shareable URL with Vercel. -

-
-
+
+

+ EMT Marketplace +

+

Under construction, check back later...

+
) } diff --git a/frontend/nextjs/src/components/ui/button.tsx b/frontend/nextjs/src/components/ui/button.tsx new file mode 100644 index 0000000..0ba4277 --- /dev/null +++ b/frontend/nextjs/src/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/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", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/frontend/nextjs/src/lib/utils.ts b/frontend/nextjs/src/lib/utils.ts new file mode 100644 index 0000000..ec79801 --- /dev/null +++ b/frontend/nextjs/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/frontend/nextjs/tailwind.config.ts b/frontend/nextjs/tailwind.config.ts index 1af3b8f..6d12b64 100644 --- a/frontend/nextjs/tailwind.config.ts +++ b/frontend/nextjs/tailwind.config.ts @@ -1,20 +1,84 @@ import type { Config } from 'tailwindcss' +/** @type {import('tailwindcss').Config} */ const config: Config = { + darkMode: ["class"], content: [ './src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', './src/app/**/*.{js,ts,jsx,tsx,mdx}', + './src/**/*.{ts,tsx}', ], theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, extend: { backgroundImage: { 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, }, }, - plugins: [], + plugins: [require("tailwindcss-animate")], } export default config From 00b6805c64d22cc95458c2474cf2b6605c382bf2 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Thu, 2 Nov 2023 03:09:45 +0000 Subject: [PATCH 02/15] -- --- frontend/nextjs/components.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/nextjs/components.json b/frontend/nextjs/components.json index e4e8e1a..a94867e 100644 --- a/frontend/nextjs/components.json +++ b/frontend/nextjs/components.json @@ -4,7 +4,7 @@ "rsc": true, "tsx": true, "tailwind": { - "config": "tailwind.config.js", + "config": "tailwind.config.ts", "css": "src/app/globals.css", "baseColor": "slate", "cssVariables": true From de72274525793ce5efd9aa434fba9f8ef47e2f0d Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Mon, 13 Nov 2023 16:02:22 +0000 Subject: [PATCH 03/15] UI: add theme, layouts & first pass at homepage --- frontend/nextjs/package.json | 2 + .../src/app/dapp/components/sidebar.tsx | 101 ++++++++++++++++++ frontend/nextjs/src/app/dapp/layout.tsx | 62 +++++++---- frontend/nextjs/src/app/dapp/page.tsx | 2 +- frontend/nextjs/src/app/layout.tsx | 17 ++- frontend/nextjs/src/app/onboarding/layout.tsx | 9 ++ frontend/nextjs/src/app/onboarding/page.tsx | 9 ++ .../components/ui/navigation/navigation.tsx | 9 ++ .../nextjs/src/components/ui/scroll-area.tsx | 48 +++++++++ .../src/components/ui/theme-provider.tsx | 9 ++ 10 files changed, 245 insertions(+), 23 deletions(-) create mode 100644 frontend/nextjs/src/app/dapp/components/sidebar.tsx create mode 100644 frontend/nextjs/src/app/onboarding/layout.tsx create mode 100644 frontend/nextjs/src/app/onboarding/page.tsx create mode 100644 frontend/nextjs/src/components/ui/navigation/navigation.tsx create mode 100644 frontend/nextjs/src/components/ui/scroll-area.tsx create mode 100644 frontend/nextjs/src/components/ui/theme-provider.tsx diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index 6144711..9272c9b 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-slot": "^1.0.2", "@rainbow-me/rainbowkit": "^1.1.4", "class-variance-authority": "^0.7.0", @@ -16,6 +17,7 @@ "ethers": "^6.8.1", "lucide-react": "^0.291.0", "next": "14.0.1", + "next-themes": "^0.2.1", "prettier": "^3.0.3", "react": "^18", "react-dom": "^18", diff --git a/frontend/nextjs/src/app/dapp/components/sidebar.tsx b/frontend/nextjs/src/app/dapp/components/sidebar.tsx new file mode 100644 index 0000000..ce62e7e --- /dev/null +++ b/frontend/nextjs/src/app/dapp/components/sidebar.tsx @@ -0,0 +1,101 @@ +import Link from "next/link" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { ScrollArea } from "@/components/ui/scroll-area" + +interface SidebarProps extends React.HTMLAttributes { + playlists?: any[] +} + +export function Sidebar({ className, playlists }: SidebarProps) { + return ( +
+
+
+
+ + + +
+ +
+
+

+ Resources +

+
+ + + + +
+
+
+
+ ) +} \ No newline at end of file diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index c61dd42..3b5735f 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -1,34 +1,60 @@ "use client"; import React from 'react'; +// import { Metadata } from 'next' import '@rainbow-me/rainbowkit/styles.css'; import { ConnectButton, RainbowKitProvider, } from '@rainbow-me/rainbowkit'; -import {emtChains, emtWagmiConfig} from "./../../../emt.config" +import { emtChains, emtWagmiConfig } from "./../../../emt.config" import { WagmiConfig } from 'wagmi'; import { ContractProvider } from '@/lib/hooks/contracts'; +import { Sidebar } from './components/sidebar'; - - +// export const metadata: Metadata = { +// title: 'Dapp View | Not Signed In', +// } export default function DappLayout({ - children, - }: { - children: React.ReactNode - }) { - return ( - + children, +}: { + children: React.ReactNode +}) { + return ( + <> + -
- -
- {children} -
+
+
+
+

MEMM!

+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ {children} +
+
+
+
+
+
+ +
-
- - ) - } +
+ + ) +} diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 03be6b3..0e31b19 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -6,7 +6,7 @@ import React from "react"; export default function RootLayout() { const { EMTMarketPlace, ExpertToken, MentorToken } = useContracts(); async function handleEMTMarketPlace() { - const val = await EMTMarketPlace._DOWNVOTE_WEIGHT(); + const val = await EMTMarketPlace.downVoteWeight(); alert(val); } diff --git a/frontend/nextjs/src/app/layout.tsx b/frontend/nextjs/src/app/layout.tsx index e02eb35..fe8bc40 100644 --- a/frontend/nextjs/src/app/layout.tsx +++ b/frontend/nextjs/src/app/layout.tsx @@ -1,13 +1,13 @@ import type { Metadata } from 'next' import { Inter } from 'next/font/google' import './globals.css' - +import { ThemeProvider } from '@/components/ui/theme-provider' const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: 'MEMM!', + description: 'Mentorship from the best', } export default function RootLayout({ @@ -18,7 +18,16 @@ export default function RootLayout({ return ( - {children} + + + {children} + + ) diff --git a/frontend/nextjs/src/app/onboarding/layout.tsx b/frontend/nextjs/src/app/onboarding/layout.tsx new file mode 100644 index 0000000..e34dd06 --- /dev/null +++ b/frontend/nextjs/src/app/onboarding/layout.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const OnboardingLayout = () => { + return ( +
OnboardingLayout
+ ) +} + +export default OnboardingLayout \ No newline at end of file diff --git a/frontend/nextjs/src/app/onboarding/page.tsx b/frontend/nextjs/src/app/onboarding/page.tsx new file mode 100644 index 0000000..e8b5644 --- /dev/null +++ b/frontend/nextjs/src/app/onboarding/page.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const OnboardingPage = () => { + return ( +
OnboardingPage
+ ) +} + +export default OnboardingPage \ No newline at end of file diff --git a/frontend/nextjs/src/components/ui/navigation/navigation.tsx b/frontend/nextjs/src/components/ui/navigation/navigation.tsx new file mode 100644 index 0000000..44b702f --- /dev/null +++ b/frontend/nextjs/src/components/ui/navigation/navigation.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const Navigation = () => { + return ( +
Navigation
+ ) +} + +export default Navigation \ No newline at end of file diff --git a/frontend/nextjs/src/components/ui/scroll-area.tsx b/frontend/nextjs/src/components/ui/scroll-area.tsx new file mode 100644 index 0000000..0b4a48d --- /dev/null +++ b/frontend/nextjs/src/components/ui/scroll-area.tsx @@ -0,0 +1,48 @@ +"use client" + +import * as React from "react" +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area" + +import { cn } from "@/lib/utils" + +const ScrollArea = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + {children} + + + + +)) +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName + +const ScrollBar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, orientation = "vertical", ...props }, ref) => ( + + + +)) +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName + +export { ScrollArea, ScrollBar } diff --git a/frontend/nextjs/src/components/ui/theme-provider.tsx b/frontend/nextjs/src/components/ui/theme-provider.tsx new file mode 100644 index 0000000..4203e6a --- /dev/null +++ b/frontend/nextjs/src/components/ui/theme-provider.tsx @@ -0,0 +1,9 @@ +"use client" + +import * as React from "react" +import { ThemeProvider as NextThemesProvider } from "next-themes" +import { type ThemeProviderProps } from "next-themes/dist/types" + +export function ThemeProvider({ children, ...props }: ThemeProviderProps) { + return {children} +} \ No newline at end of file From 9dadc24b58308acbac355e2f3e29e3a6c7658ab0 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 03:54:26 +0000 Subject: [PATCH 04/15] refactored web3 wallet providers --- frontend/nextjs/package.json | 2 + .../src/app/dapp/components/providers.tsx | 27 +++++++++++++ frontend/nextjs/src/app/dapp/layout.tsx | 38 +++++++++---------- frontend/nextjs/src/app/globals.css | 34 ++++++++++++++++- frontend/nextjs/src/components/ui/button.tsx | 2 +- .../nextjs/src/components/ui/forms/search.tsx | 13 +++++++ frontend/nextjs/src/components/ui/input.tsx | 25 ++++++++++++ frontend/nextjs/tailwind.config.ts | 2 +- 8 files changed, 119 insertions(+), 24 deletions(-) create mode 100644 frontend/nextjs/src/app/dapp/components/providers.tsx create mode 100644 frontend/nextjs/src/components/ui/forms/search.tsx create mode 100644 frontend/nextjs/src/components/ui/input.tsx diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index 9272c9b..56cfdfb 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-slot": "^1.0.2", "@rainbow-me/rainbowkit": "^1.1.4", @@ -21,6 +22,7 @@ "prettier": "^3.0.3", "react": "^18", "react-dom": "^18", + "react-icons": "^4.11.0", "tailwind-merge": "^2.0.0", "tailwindcss-animate": "^1.0.7", "viem": "^1.18.1", diff --git a/frontend/nextjs/src/app/dapp/components/providers.tsx b/frontend/nextjs/src/app/dapp/components/providers.tsx new file mode 100644 index 0000000..da9aa5b --- /dev/null +++ b/frontend/nextjs/src/app/dapp/components/providers.tsx @@ -0,0 +1,27 @@ +"use client"; +import React from 'react'; +import '@rainbow-me/rainbowkit/styles.css'; +import { + RainbowKitProvider, +} from '@rainbow-me/rainbowkit'; + +import { emtChains, emtWagmiConfig } from "../../../../emt.config" +import { WagmiConfig } from 'wagmi'; +import { ContractProvider } from '@/lib/hooks/contracts'; + +// Web3 Wallet Connector's Provider +export default function DappProviders({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + + {children} + + + + ) +} diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index 3b5735f..cc55386 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -1,20 +1,19 @@ -"use client"; + import React from 'react'; -// import { Metadata } from 'next' +import { Metadata } from 'next' import '@rainbow-me/rainbowkit/styles.css'; import { - ConnectButton, - RainbowKitProvider, + ConnectButton } from '@rainbow-me/rainbowkit'; - -import { emtChains, emtWagmiConfig } from "./../../../emt.config" -import { WagmiConfig } from 'wagmi'; -import { ContractProvider } from '@/lib/hooks/contracts'; import { Sidebar } from './components/sidebar'; +import { Search } from '@/components/ui/forms/search'; +import { Button } from '@/components/ui/button'; +import { HiOutlinePencilAlt } from "react-icons/hi" +import DappProviders from './components/providers'; -// export const metadata: Metadata = { -// title: 'Dapp View | Not Signed In', -// } +export const metadata: Metadata = { + title: 'MEMM! Homepage', +} export default function DappLayout({ children, @@ -23,25 +22,27 @@ export default function DappLayout({ }) { return ( <> - - - +

MEMM!

+ +
-
+
- +
{children} @@ -51,10 +52,7 @@ export default function DappLayout({
- - - - + ) } diff --git a/frontend/nextjs/src/app/globals.css b/frontend/nextjs/src/app/globals.css index 6a75725..a3ac77c 100644 --- a/frontend/nextjs/src/app/globals.css +++ b/frontend/nextjs/src/app/globals.css @@ -3,6 +3,8 @@ @tailwind utilities; @layer base { + + :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; @@ -28,14 +30,14 @@ --destructive: 0 84.2% 60.2%; --destructive-foreground: 210 40% 98%; - --border: 214.3 31.8% 91.4%; + --stroke: 0, 0%, 98%, 0.1; --input: 214.3 31.8% 91.4%; --ring: 222.2 84% 4.9%; --radius: 0.5rem; } - .dark { + /* .dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%; @@ -63,6 +65,34 @@ --border: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%; --ring: 212.7 26.8% 83.9%; + } */ + + .dark { + --accent-2: hsl(241, 77%, 63%); + --primary-black: hsl(0, 0%, 0%); + --accent-4: hsl(0, 91%, 71%); + --white: hsl(0, 0%, 100%); + --accent-1: hsl(222, 47%, 11%); + --accent-3: hsl(330, 81%, 60%); + --text-alt: hsl(230, 39%, 68%); + --text-muted: hsl(226, 22%, 73%); + --text: hsl(226, 100%, 94%); + --stroke: 0, 0%, 98%, 0.1; + --alt-stroke: hsla(0, 0%, 98%, 0.05); + --accent-shade: hsl(222, 46%, 17%); + --gray-200: hsl(216, 11%, 91%); + --gray-50: hsl(0, 0%, 98%); + --gray-100: hsl(220, 20%, 97%); + --gray-300: hsl(210, 9%, 82%); + --gray-400: hsl(212, 8%, 65%); + --gray-700: hsl(208, 9%, 30%); + --gray-600: hsl(208, 7%, 37%); + --gray-500: hsl(212, 7%, 43%); + --gray-800: hsl(208, 10%, 25%); + --gray-900: hsl(210, 12%, 16%); + --primary-white: hsl(0, 0%, 100%); + --gray-1000: hsl(210, 12%, 16%); + --white: hsl(0, 0%, 100%); } } diff --git a/frontend/nextjs/src/components/ui/button.tsx b/frontend/nextjs/src/components/ui/button.tsx index 0ba4277..26a2b18 100644 --- a/frontend/nextjs/src/components/ui/button.tsx +++ b/frontend/nextjs/src/components/ui/button.tsx @@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/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", + "inline-flex items-center justify-center whitespace-nowrap rounded-full 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", { variants: { variant: { diff --git a/frontend/nextjs/src/components/ui/forms/search.tsx b/frontend/nextjs/src/components/ui/forms/search.tsx new file mode 100644 index 0000000..8fcc713 --- /dev/null +++ b/frontend/nextjs/src/components/ui/forms/search.tsx @@ -0,0 +1,13 @@ +import { Input } from "@/components/ui/input" + +export function Search() { + return ( +
+ +
+ ) +} \ No newline at end of file diff --git a/frontend/nextjs/src/components/ui/input.tsx b/frontend/nextjs/src/components/ui/input.tsx new file mode 100644 index 0000000..677d05f --- /dev/null +++ b/frontend/nextjs/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/frontend/nextjs/tailwind.config.ts b/frontend/nextjs/tailwind.config.ts index 6d12b64..fc73c39 100644 --- a/frontend/nextjs/tailwind.config.ts +++ b/frontend/nextjs/tailwind.config.ts @@ -24,7 +24,7 @@ const config: Config = { 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, colors: { - border: "hsl(var(--border))", + border: "hsla(var(--stroke))", input: "hsl(var(--input))", ring: "hsl(var(--ring))", background: "hsl(var(--background))", From 5e554ca303519a4ae84493cf583bf9260411552f Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 05:56:29 +0000 Subject: [PATCH 05/15] add theme colors, fixed up sidebar --- .../src/app/dapp/components/sidebar.tsx | 113 +++++++----------- frontend/nextjs/src/app/globals.css | 90 +++++++++----- frontend/nextjs/src/components/ui/button.tsx | 5 +- frontend/nextjs/tailwind.config.ts | 23 ++-- 4 files changed, 124 insertions(+), 107 deletions(-) diff --git a/frontend/nextjs/src/app/dapp/components/sidebar.tsx b/frontend/nextjs/src/app/dapp/components/sidebar.tsx index ce62e7e..dd08e1d 100644 --- a/frontend/nextjs/src/app/dapp/components/sidebar.tsx +++ b/frontend/nextjs/src/app/dapp/components/sidebar.tsx @@ -2,98 +2,73 @@ import Link from "next/link" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { ScrollArea } from "@/components/ui/scroll-area" +import {HiOutlineHome, HiOutlineUser, HiOutlineEnvelope} from 'react-icons/hi2' interface SidebarProps extends React.HTMLAttributes { playlists?: any[] } +const primaryNavigationLinks = [ + { + title: "Home", + icon: HiOutlineHome, + isActive: false, + href: "/dapp" + }, + { + title: "My Profile", + icon: HiOutlineUser, + isActive: false, + href: "/my-profile" + }, + { + title: "Notifications", + icon: HiOutlineEnvelope, + isActive: false, + href: "/notifications" + } +] + export function Sidebar({ className, playlists }: SidebarProps) { return (
- - - + {primaryNavigationLinks.map(link => ( + + ))}
- +
-

- Resources -

-
- - - -
+
+
diff --git a/frontend/nextjs/src/app/globals.css b/frontend/nextjs/src/app/globals.css index a3ac77c..8945254 100644 --- a/frontend/nextjs/src/app/globals.css +++ b/frontend/nextjs/src/app/globals.css @@ -5,7 +5,7 @@ @layer base { - :root { + /* :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%; @@ -35,7 +35,7 @@ --ring: 222.2 84% 4.9%; --radius: 0.5rem; - } + } */ /* .dark { --background: 222.2 84% 4.9%; @@ -67,32 +67,68 @@ --ring: 212.7 26.8% 83.9%; } */ + :root { + --primary-black: 0deg 0% 0%; + --white: 0deg 0% 100%; + --primary-white: 0deg 0% 100%; + + --accent-shade: 222deg 46% 17%; + --accent-1: 222deg 47% 11%; + --accent-2: 241deg 77% 63%; + --accent-3: 330deg 81% 60%; + --accent-4: 0deg 91% 71%; + + --white: 0deg 0% 100%; + --text: 226deg 100% 94%; + --text-alt: 230deg 39% 68%; + --text-muted: 226deg 22% 73%; + + --stroke: 0deg 0% 98%; + --alt-stroke: 0deg 0% 98%; + + --gray-50: 0deg 0% 98%; + --gray-100: 220deg 20% 97%; + --gray-200: 216deg 11% 91%; + --gray-300: 210deg 9% 82%; + --gray-400: 212deg 8% 65%; + --gray-700: 208deg 9% 30%; + --gray-600: 208deg 7% 37%; + --gray-500: 212deg 7% 43%; + --gray-800: 208deg 10% 25%; + --gray-900: 210deg 12% 16%; + --gray-1000: 210deg 12% 16%; + + --radius: 0.5rem; + } + .dark { - --accent-2: hsl(241, 77%, 63%); - --primary-black: hsl(0, 0%, 0%); - --accent-4: hsl(0, 91%, 71%); - --white: hsl(0, 0%, 100%); - --accent-1: hsl(222, 47%, 11%); - --accent-3: hsl(330, 81%, 60%); - --text-alt: hsl(230, 39%, 68%); - --text-muted: hsl(226, 22%, 73%); - --text: hsl(226, 100%, 94%); - --stroke: 0, 0%, 98%, 0.1; - --alt-stroke: hsla(0, 0%, 98%, 0.05); - --accent-shade: hsl(222, 46%, 17%); - --gray-200: hsl(216, 11%, 91%); - --gray-50: hsl(0, 0%, 98%); - --gray-100: hsl(220, 20%, 97%); - --gray-300: hsl(210, 9%, 82%); - --gray-400: hsl(212, 8%, 65%); - --gray-700: hsl(208, 9%, 30%); - --gray-600: hsl(208, 7%, 37%); - --gray-500: hsl(212, 7%, 43%); - --gray-800: hsl(208, 10%, 25%); - --gray-900: hsl(210, 12%, 16%); - --primary-white: hsl(0, 0%, 100%); - --gray-1000: hsl(210, 12%, 16%); - --white: hsl(0, 0%, 100%); + --primary-black: 0deg 0% 0%; + --primary-white: 0deg 0% 100%; + + --accent-shade: 222deg 46% 17%; + --accent-1: 222deg 47% 11%; + --accent-2: 241deg 77% 63%; + --accent-3: 330deg 81% 60%; + --accent-4: 0deg 91% 71%; + + --text: 226deg 100% 94%; + --text-alt: 230deg 39% 68%; + --text-muted: 226deg 22% 73%; + + --stroke: 0deg 0% 98%; + --alt-stroke: 0deg 0% 98%; + + --gray-50: 0deg 0% 98%; + --gray-100: 220deg 20% 97%; + --gray-200: 216deg 11% 91%; + --gray-300: 210deg 9% 82%; + --gray-400: 212deg 8% 65%; + --gray-700: 208deg 9% 30%; + --gray-600: 208deg 7% 37%; + --gray-500: 212deg 7% 43%; + --gray-800: 208deg 10% 25%; + --gray-900: 210deg 12% 16%; + --gray-1000: 210deg 12% 16%; } } diff --git a/frontend/nextjs/src/components/ui/button.tsx b/frontend/nextjs/src/components/ui/button.tsx index 26a2b18..6d67f86 100644 --- a/frontend/nextjs/src/components/ui/button.tsx +++ b/frontend/nextjs/src/components/ui/button.tsx @@ -9,6 +9,7 @@ const buttonVariants = cva( { variants: { variant: { + gradient: "bg-pink-gradient hover:bg-reverse-pink-gradient hover:text-white/80", default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", @@ -16,8 +17,8 @@ const buttonVariants = cva( "border border-input bg-background hover:bg-accent hover:text-accent-foreground", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", + ghost: "hover:bg-accent-shade hover:text-accent-foreground", + link: "text-foreground underline-offset-4 hover:underline", }, size: { default: "h-10 px-4 py-2", diff --git a/frontend/nextjs/tailwind.config.ts b/frontend/nextjs/tailwind.config.ts index fc73c39..3e661c0 100644 --- a/frontend/nextjs/tailwind.config.ts +++ b/frontend/nextjs/tailwind.config.ts @@ -22,13 +22,22 @@ const config: Config = { 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + 'pink-gradient': 'linear-gradient(96deg, hsl(var(--accent-3)) 0%, hsl(var(--accent-4)) 137%)', + 'reverse-pink-gradient': 'linear-gradient(96deg, hsl(var(--accent-4)) 0%, hsl(var(--accent-3)) 137%)', }, colors: { - border: "hsla(var(--stroke))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", + border: "hsl(var(--stroke) / 0.1)", + input: "hsl(var(--accent-shade))", + ring: "hsl(var(--stroke) / 0.1)", + background: "hsl(var(--accent-1))", + foreground: "hsl(var(--text))", + 'alt': "hsl(var(--text-alt))", + 'muted': "hsl(var(--text-muted))", + 'accent-shade': 'hsl(var(--accent-shade))', + 'accent-1': 'hsl(var(--accent-1))', + 'accent-2': 'hsl(var(--accent-2))', + 'accent-3': 'hsl(var(--accent-3))', + 'accent-4': 'hsl(var(--accent-4))', primary: { DEFAULT: "hsl(var(--primary))", foreground: "hsl(var(--primary-foreground))", @@ -41,10 +50,6 @@ const config: Config = { DEFAULT: "hsl(var(--destructive))", foreground: "hsl(var(--destructive-foreground))", }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, accent: { DEFAULT: "hsl(var(--accent))", foreground: "hsl(var(--accent-foreground))", From 4faae7605f24ef8128c21937c3a2db7f7118d7ea Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 06:41:48 +0000 Subject: [PATCH 06/15] top navbar styling --- .../nextjs/src/app/dapp/components/providers.tsx | 7 ++++++- frontend/nextjs/src/app/dapp/components/sidebar.tsx | 8 ++++---- frontend/nextjs/src/app/dapp/layout.tsx | 12 ++++++++++-- frontend/nextjs/src/app/globals.css | 2 -- frontend/nextjs/src/components/ui/forms/search.tsx | 4 ++-- frontend/nextjs/tailwind.config.ts | 1 + 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/frontend/nextjs/src/app/dapp/components/providers.tsx b/frontend/nextjs/src/app/dapp/components/providers.tsx index da9aa5b..bc29b8a 100644 --- a/frontend/nextjs/src/app/dapp/components/providers.tsx +++ b/frontend/nextjs/src/app/dapp/components/providers.tsx @@ -3,6 +3,7 @@ import React from 'react'; import '@rainbow-me/rainbowkit/styles.css'; import { RainbowKitProvider, + darkTheme } from '@rainbow-me/rainbowkit'; import { emtChains, emtWagmiConfig } from "../../../../emt.config" @@ -17,7 +18,11 @@ export default function DappProviders({ }) { return ( - + {children} diff --git a/frontend/nextjs/src/app/dapp/components/sidebar.tsx b/frontend/nextjs/src/app/dapp/components/sidebar.tsx index dd08e1d..5b4e3a1 100644 --- a/frontend/nextjs/src/app/dapp/components/sidebar.tsx +++ b/frontend/nextjs/src/app/dapp/components/sidebar.tsx @@ -5,7 +5,7 @@ import { ScrollArea } from "@/components/ui/scroll-area" import {HiOutlineHome, HiOutlineUser, HiOutlineEnvelope} from 'react-icons/hi2' interface SidebarProps extends React.HTMLAttributes { - playlists?: any[] + } const primaryNavigationLinks = [ @@ -29,14 +29,14 @@ const primaryNavigationLinks = [ } ] -export function Sidebar({ className, playlists }: SidebarProps) { +export function Sidebar({ className }: SidebarProps) { return (
- {primaryNavigationLinks.map(link => ( - - +
diff --git a/frontend/nextjs/src/app/globals.css b/frontend/nextjs/src/app/globals.css index 8945254..deb2264 100644 --- a/frontend/nextjs/src/app/globals.css +++ b/frontend/nextjs/src/app/globals.css @@ -84,7 +84,6 @@ --text-muted: 226deg 22% 73%; --stroke: 0deg 0% 98%; - --alt-stroke: 0deg 0% 98%; --gray-50: 0deg 0% 98%; --gray-100: 220deg 20% 97%; @@ -116,7 +115,6 @@ --text-muted: 226deg 22% 73%; --stroke: 0deg 0% 98%; - --alt-stroke: 0deg 0% 98%; --gray-50: 0deg 0% 98%; --gray-100: 220deg 20% 97%; diff --git a/frontend/nextjs/src/components/ui/forms/search.tsx b/frontend/nextjs/src/components/ui/forms/search.tsx index 8fcc713..6906e7f 100644 --- a/frontend/nextjs/src/components/ui/forms/search.tsx +++ b/frontend/nextjs/src/components/ui/forms/search.tsx @@ -5,8 +5,8 @@ export function Search() {
) diff --git a/frontend/nextjs/tailwind.config.ts b/frontend/nextjs/tailwind.config.ts index 3e661c0..2879920 100644 --- a/frontend/nextjs/tailwind.config.ts +++ b/frontend/nextjs/tailwind.config.ts @@ -27,6 +27,7 @@ const config: Config = { }, colors: { border: "hsl(var(--stroke) / 0.1)", + 'alt-stroke': "hsl(var(--stroke) / 0.05)", input: "hsl(var(--accent-shade))", ring: "hsl(var(--stroke) / 0.1)", background: "hsl(var(--accent-1))", From 0ab15d2e3991da192087e3a5b966bc3f1848141b Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 07:43:42 +0000 Subject: [PATCH 07/15] wip --- frontend/nextjs/package.json | 1 + frontend/nextjs/src/app/dapp/page.tsx | 26 +++++- frontend/nextjs/src/components/ui/card.tsx | 79 +++++++++++++++++++ .../nextjs/src/components/ui/post-card.tsx | 32 ++++++++ frontend/nextjs/src/components/ui/tabs.tsx | 55 +++++++++++++ 5 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 frontend/nextjs/src/components/ui/card.tsx create mode 100644 frontend/nextjs/src/components/ui/post-card.tsx create mode 100644 frontend/nextjs/src/components/ui/tabs.tsx diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index 56cfdfb..6f653ad 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -12,6 +12,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-tabs": "^1.0.4", "@rainbow-me/rainbowkit": "^1.1.4", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 0e31b19..bf3152c 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -2,6 +2,9 @@ import { Button } from "@/components/ui/button"; import { useContracts } from "@/lib/hooks/contracts"; import React from "react"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" +import PostCard from "@/components/ui/post-card"; + export default function RootLayout() { const { EMTMarketPlace, ExpertToken, MentorToken } = useContracts(); @@ -20,11 +23,28 @@ export default function RootLayout() { alert(val); } + // return ( + //
+ // + // + // + //
+ // ); + return (
- - - + + + Following + Design + + + + + + + +
); } diff --git a/frontend/nextjs/src/components/ui/card.tsx b/frontend/nextjs/src/components/ui/card.tsx new file mode 100644 index 0000000..afa13ec --- /dev/null +++ b/frontend/nextjs/src/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/frontend/nextjs/src/components/ui/post-card.tsx b/frontend/nextjs/src/components/ui/post-card.tsx new file mode 100644 index 0000000..93360e5 --- /dev/null +++ b/frontend/nextjs/src/components/ui/post-card.tsx @@ -0,0 +1,32 @@ +import React from 'react' +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card" + + +const PostCard = () => { + return ( +
+ + + Card Title + Card Description + + +

Card Content

+
+ +

Card Footer

+
+
+ +
+ ) +} + +export default PostCard \ No newline at end of file diff --git a/frontend/nextjs/src/components/ui/tabs.tsx b/frontend/nextjs/src/components/ui/tabs.tsx new file mode 100644 index 0000000..26eb109 --- /dev/null +++ b/frontend/nextjs/src/components/ui/tabs.tsx @@ -0,0 +1,55 @@ +"use client" + +import * as React from "react" +import * as TabsPrimitive from "@radix-ui/react-tabs" + +import { cn } from "@/lib/utils" + +const Tabs = TabsPrimitive.Root + +const TabsList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsList.displayName = TabsPrimitive.List.displayName + +const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName + +const TabsContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsContent.displayName = TabsPrimitive.Content.displayName + +export { Tabs, TabsList, TabsTrigger, TabsContent } From 9ffc9a6d140bd9a4e5c5cc1bf067e970dc74f87b Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 14:30:27 +0000 Subject: [PATCH 08/15] added post-card --- frontend/nextjs/next.config.js | 12 ++- frontend/nextjs/package.json | 1 + frontend/nextjs/src/app/dapp/page.tsx | 91 ++++++++++++++++++- .../nextjs/src/components/ui/post-card.tsx | 78 +++++++++++++--- .../nextjs/src/components/ui/separator.tsx | 31 +++++++ 5 files changed, 198 insertions(+), 15 deletions(-) create mode 100644 frontend/nextjs/src/components/ui/separator.tsx diff --git a/frontend/nextjs/next.config.js b/frontend/nextjs/next.config.js index 767719f..2a708d8 100644 --- a/frontend/nextjs/next.config.js +++ b/frontend/nextjs/next.config.js @@ -1,4 +1,14 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {} +const nextConfig = { + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'images.unsplash.com', + port: '', + }, + ], + }, +} module.exports = nextConfig diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index 6f653ad..97f618e 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -11,6 +11,7 @@ "dependencies": { "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", "@rainbow-me/rainbowkit": "^1.1.4", diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index bf3152c..6407b66 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -4,6 +4,82 @@ import { useContracts } from "@/lib/hooks/contracts"; import React from "react"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import PostCard from "@/components/ui/post-card"; +import { Separator } from "@/components/ui/separator"; + +const dummyPosts = [ + { + author: { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true" + }, + post: { + title: "I’m an experienced CEO. I applied for 1001 positions. This is what happened.", + body: "Et pulvinar purus purus pharetra non lobortis nunc. Consectetur feugiat orci consectetur consectetur facilisi. Urna cursus risus nisl sit suscipit nunc sed id in. ", + image: "https://images.unsplash.com/photo-1577100078279-b3445eae827c?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + }, + metadata: { + upvotes: 435, + downvotes: 23, + permalink: "something.com", + datePublished: "5hrs ago" + } + }, + { + author: { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true" + }, + post: { + title: "I’m an experienced CEO. I applied for 1001 positions. This is what happened.", + body: "Et pulvinar purus purus pharetra non lobortis nunc. Consectetur feugiat orci consectetur consectetur facilisi. Urna cursus risus nisl sit suscipit nunc sed id in. ", + image: "https://images.unsplash.com/photo-1577100078279-b3445eae827c?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + }, + metadata: { + upvotes: 435, + downvotes: 23, + permalink: "something.com", + datePublished: "5hrs ago" + } + }, + { + author: { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true" + }, + post: { + title: "I’m an experienced CEO. I applied for 1001 positions. This is what happened.", + body: "Et pulvinar purus purus pharetra non lobortis nunc. Consectetur feugiat orci consectetur consectetur facilisi. Urna cursus risus nisl sit suscipit nunc sed id in. ", + image: "https://images.unsplash.com/photo-1577100078279-b3445eae827c?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + }, + metadata: { + upvotes: 435, + downvotes: 23, + permalink: "something.com", + datePublished: "5hrs ago" + } + }, + { + author: { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true" + }, + post: { + title: "I’m an experienced CEO. I applied for 1001 positions. This is what happened.", + body: "Et pulvinar purus purus pharetra non lobortis nunc. Consectetur feugiat orci consectetur consectetur facilisi. Urna cursus risus nisl sit suscipit nunc sed id in. ", + image: "https://images.unsplash.com/photo-1577100078279-b3445eae827c?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" + }, + metadata: { + upvotes: 435, + downvotes: 23, + permalink: "something.com", + datePublished: "5hrs ago" + } + }, +] export default function RootLayout() { @@ -13,6 +89,8 @@ export default function RootLayout() { alert(val); } + console.log('dummy', dummyPosts) + async function handleExpertToken() { const val = await ExpertToken.MINTER_ROLE(); alert(val); @@ -33,16 +111,23 @@ export default function RootLayout() { return (
- + Following Design - +
+ {dummyPosts.map((post, key) => { + return <> + + + + })} +
- + {/* */}
diff --git a/frontend/nextjs/src/components/ui/post-card.tsx b/frontend/nextjs/src/components/ui/post-card.tsx index 93360e5..4535bca 100644 --- a/frontend/nextjs/src/components/ui/post-card.tsx +++ b/frontend/nextjs/src/components/ui/post-card.tsx @@ -7,25 +7,81 @@ import { CardHeader, CardTitle, } from "@/components/ui/card" +import Image from 'next/image' +import Link from 'next/link'; +import { HiCheckBadge, HiOutlineHandThumbUp, HiOutlineHandThumbDown, HiOutlineShare } from "react-icons/hi2"; +import { Button } from '@/components/ui/button'; -const PostCard = () => { +const PostCard = ({data}: any) => { + const {post, author, metadata} = data + return ( -
- - - Card Title - Card Description + + + +
+
+ {`${author.name}-avatar`} +
+
+
+

{author.name}

+ {author.mentor === "true" && } +
+ +
+
+
- -

Card Content

+ + {post.title} + {post.body} +
+ {`${post.title} +
- -

Card Footer

+ +
+
+ +
+ {metadata.upvotes} +
+ +
+
+ +
+
+ +
-
+ ) } diff --git a/frontend/nextjs/src/components/ui/separator.tsx b/frontend/nextjs/src/components/ui/separator.tsx new file mode 100644 index 0000000..12d81c4 --- /dev/null +++ b/frontend/nextjs/src/components/ui/separator.tsx @@ -0,0 +1,31 @@ +"use client" + +import * as React from "react" +import * as SeparatorPrimitive from "@radix-ui/react-separator" + +import { cn } from "@/lib/utils" + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref + ) => ( + + ) +) +Separator.displayName = SeparatorPrimitive.Root.displayName + +export { Separator } From 907e2a0293f506f64a0eb458399f9af3d837539e Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Tue, 14 Nov 2023 14:46:59 +0000 Subject: [PATCH 09/15] update homepage --- .../src/app/dapp/components/right-sidebar.tsx | 76 +++++++++++++++++++ frontend/nextjs/src/app/dapp/layout.tsx | 68 +++++++++-------- frontend/nextjs/src/app/dapp/page.tsx | 21 +++-- .../nextjs/src/components/ui/post-card.tsx | 2 +- 4 files changed, 128 insertions(+), 39 deletions(-) create mode 100644 frontend/nextjs/src/app/dapp/components/right-sidebar.tsx diff --git a/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx b/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx new file mode 100644 index 0000000..08f8a11 --- /dev/null +++ b/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx @@ -0,0 +1,76 @@ +import Link from "next/link" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { ScrollArea } from "@/components/ui/scroll-area" +import {HiOutlineHome, HiOutlineUser, HiOutlineEnvelope} from 'react-icons/hi2' + +interface SidebarProps extends React.HTMLAttributes { + +} + +const primaryNavigationLinks = [ + { + title: "Home", + icon: HiOutlineHome, + isActive: false, + href: "/dapp" + }, + { + title: "My Profile", + icon: HiOutlineUser, + isActive: false, + href: "/my-profile" + }, + { + title: "Notifications", + icon: HiOutlineEnvelope, + isActive: false, + href: "/notifications" + } +] + +export function RightSidebar({ className }: SidebarProps) { + return ( +
+
+
+
+ {primaryNavigationLinks.map((link, key)=> ( + + ))} +
+ +
+
+
+

+ Resources +

+
+ + + + +
+
+ +
+
+
+ ) +} \ No newline at end of file diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index dedb598..127d929 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -10,6 +10,7 @@ import { Search } from '@/components/ui/forms/search'; import { Button } from '@/components/ui/button'; import { HiOutlinePencilAlt } from "react-icons/hi" import DappProviders from './components/providers'; +import { ScrollArea } from "@/components/ui/scroll-area" export const metadata: Metadata = { title: 'MEMM! Homepage', @@ -23,43 +24,48 @@ export default function DappLayout({ return ( <> -
-
-
-

MEMM!

-
- - - -
-
+
+
+
+

MEMM!

+
+ + +
-
+
+
+ + +
+
+
+
+ +
+ +
+ + {children} + -
-
-
-
- -
-
- {children} -
-
+
+
+
) diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 6407b66..5f9403e 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -118,16 +118,23 @@ export default function RootLayout() {
- {dummyPosts.map((post, key) => { - return <> - - - - })} + {dummyPosts.map((post, key) => { + return <> + + + + })}
- {/* */} +
+ {dummyPosts.map((post, key) => { + return <> + + + + })} +
diff --git a/frontend/nextjs/src/components/ui/post-card.tsx b/frontend/nextjs/src/components/ui/post-card.tsx index 4535bca..8f2efba 100644 --- a/frontend/nextjs/src/components/ui/post-card.tsx +++ b/frontend/nextjs/src/components/ui/post-card.tsx @@ -51,7 +51,7 @@ const PostCard = ({data}: any) => { {`${post.title} From c499609992206e04eb748dd1b3082ca0a81a1cb3 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Wed, 15 Nov 2023 01:03:41 +0000 Subject: [PATCH 10/15] fixed up right sidebar --- .../src/app/dapp/components/right-sidebar.tsx | 38 +--- frontend/nextjs/src/app/dapp/layout.tsx | 15 +- frontend/nextjs/src/app/dapp/page.tsx | 189 +++++++++++++++--- frontend/nextjs/src/components/ui/badge.tsx | 36 ++++ .../nextjs/src/components/ui/post-card.tsx | 5 +- 5 files changed, 204 insertions(+), 79 deletions(-) create mode 100644 frontend/nextjs/src/components/ui/badge.tsx diff --git a/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx b/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx index 08f8a11..15b757d 100644 --- a/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx +++ b/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx @@ -29,46 +29,12 @@ const primaryNavigationLinks = [ } ] -export function RightSidebar({ className }: SidebarProps) { +export function RightSidebar({ className, children }: SidebarProps) { return (
-
- {primaryNavigationLinks.map((link, key)=> ( - - ))} -
- -
-
-
-

- Resources -

-
- - - - -
-
- + {children}
diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index 127d929..5bc1042 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -6,6 +6,7 @@ import { ConnectButton } from '@rainbow-me/rainbowkit'; import { Sidebar } from './components/sidebar'; +import { RightSidebar } from './components/right-sidebar'; import { Search } from '@/components/ui/forms/search'; import { Button } from '@/components/ui/button'; import { HiOutlinePencilAlt } from "react-icons/hi" @@ -18,8 +19,10 @@ export const metadata: Metadata = { export default function DappLayout({ children, + rightSidebarContent }: { children: React.ReactNode + rightSidebarContent: React.ReactNode }) { return ( <> @@ -52,16 +55,10 @@ export default function DappLayout({
-
- -
- - {children} - - -
+
+ {children}
- +
diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 5f9403e..5baada8 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -1,10 +1,16 @@ "use client"; +import React from "react"; import { Button } from "@/components/ui/button"; import { useContracts } from "@/lib/hooks/contracts"; -import React from "react"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import PostCard from "@/components/ui/post-card"; import { Separator } from "@/components/ui/separator"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { RightSidebar } from "./components/right-sidebar"; +import Image from "next/image"; +import {HiCheckBadge, HiOutlineFire} from "react-icons/hi2" +import { Badge } from "@/components/ui/badge"; +import Link from "next/link"; const dummyPosts = [ { @@ -81,16 +87,49 @@ const dummyPosts = [ }, ] +const topCreatorList = [ + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "false", + skill: "UI Design", + href: "/profile/naval", + ment: 134 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "Java", + href: "/profile/naval", + ment: 693 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "Ruby", + href: "/profile/naval", + ment: 953 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "AI", + href: "/profile/naval", + ment: 422 + }, +] + export default function RootLayout() { const { EMTMarketPlace, ExpertToken, MentorToken } = useContracts(); async function handleEMTMarketPlace() { - const val = await EMTMarketPlace.downVoteWeight(); - alert(val); + const val = await EMTMarketPlace.downVoteWeight(); + alert(val); } - console.log('dummy', dummyPosts) - async function handleExpertToken() { const val = await ExpertToken.MINTER_ROLE(); alert(val); @@ -110,33 +149,123 @@ export default function RootLayout() { // ); return ( -
- - - Following - Design - - -
- {dummyPosts.map((post, key) => { - return <> - - - - })} +
+
+ +
+ + + Following + Design + + +
+ {dummyPosts.map((post, key) => { + return <> + + + + })} +
+
+ +
+ {dummyPosts.map((post, key) => { + return <> + + + + })} +
+
+
- - -
- {dummyPosts.map((post, key) => { - return <> - - - - })} + +
+ + <> + +
+

+ Top Creators +

+
+ {topCreatorList.map((profile, key) => { + return +
+
+ {`${profile.name}-avatar`} +
+
+
+

{profile.name}

+ {profile.mentor === "true" && } +
+ {profile.skill} +
+
+
+ +
+ 245 MENT +
+
+ + })} + + +
-
- + +
+

+ Who to Follow +

+
+ {topCreatorList.map((profile, key) => { + return +
+
+ {`${profile.name}-avatar`} +
+
+
+

{profile.name}

+ {profile.mentor === "true" && } +
+ {profile.skill} +
+
+
+ +
+ 245 MENT +
+
+ + })} + + +
+
+ +
+ + ); } diff --git a/frontend/nextjs/src/components/ui/badge.tsx b/frontend/nextjs/src/components/ui/badge.tsx new file mode 100644 index 0000000..46f9936 --- /dev/null +++ b/frontend/nextjs/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-1.5 py-0.1 text-[11px] font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-accent-2 text-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-accent-shade text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/frontend/nextjs/src/components/ui/post-card.tsx b/frontend/nextjs/src/components/ui/post-card.tsx index 8f2efba..c8da2ad 100644 --- a/frontend/nextjs/src/components/ui/post-card.tsx +++ b/frontend/nextjs/src/components/ui/post-card.tsx @@ -22,11 +22,8 @@ const PostCard = ({data}: any) => {
- Date: Wed, 15 Nov 2023 01:49:42 +0000 Subject: [PATCH 11/15] cleaned up tabs --- frontend/nextjs/src/app/dapp/layout.tsx | 2 +- frontend/nextjs/src/app/dapp/page.tsx | 8 ++++---- frontend/nextjs/src/components/ui/tabs.tsx | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index 5bc1042..4e7cb12 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -55,7 +55,7 @@ export default function DappLayout({
-
+
{children}
diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 5baada8..817c298 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -8,7 +8,7 @@ import { Separator } from "@/components/ui/separator"; import { ScrollArea } from "@/components/ui/scroll-area"; import { RightSidebar } from "./components/right-sidebar"; import Image from "next/image"; -import {HiCheckBadge, HiOutlineFire} from "react-icons/hi2" +import { HiCheckBadge, HiOutlineFire } from "react-icons/hi2" import { Badge } from "@/components/ui/badge"; import Link from "next/link"; @@ -150,7 +150,7 @@ export default function RootLayout() { return (
-
+
@@ -182,9 +182,9 @@ export default function RootLayout() {
- + <> - +

Top Creators diff --git a/frontend/nextjs/src/components/ui/tabs.tsx b/frontend/nextjs/src/components/ui/tabs.tsx index 26eb109..02bd208 100644 --- a/frontend/nextjs/src/components/ui/tabs.tsx +++ b/frontend/nextjs/src/components/ui/tabs.tsx @@ -14,7 +14,7 @@ const TabsList = React.forwardRef< Date: Wed, 15 Nov 2023 09:00:56 +0000 Subject: [PATCH 12/15] fix build error --- frontend/nextjs/src/app/dapp/layout.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index 4e7cb12..8e156c3 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -18,11 +18,9 @@ export const metadata: Metadata = { } export default function DappLayout({ - children, - rightSidebarContent + children }: { children: React.ReactNode - rightSidebarContent: React.ReactNode }) { return ( <> From 7b6833eba5bc9d3256b2df176476e1ad2fdb3d97 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Thu, 16 Nov 2023 02:27:16 +0000 Subject: [PATCH 13/15] started read post & create post screens --- frontend/nextjs/package.json | 7 +- .../{components => _components}/providers.tsx | 0 .../right-sidebar.tsx | 0 .../{components => _components}/sidebar.tsx | 0 frontend/nextjs/src/app/dapp/layout.tsx | 6 +- .../nextjs/src/app/dapp/p/[slug]/page.tsx | 221 ++++++++++++++++++ .../p/create/_components/create-post-form.tsx | 27 +++ .../nextjs/src/app/dapp/p/create/page.tsx | 28 +++ frontend/nextjs/src/app/dapp/page.tsx | 2 +- frontend/nextjs/src/components/ui/form.tsx | 176 ++++++++++++++ frontend/nextjs/src/components/ui/label.tsx | 26 +++ .../nextjs/src/components/ui/post-card.tsx | 2 +- frontend/nextjs/src/components/ui/toast.tsx | 127 ++++++++++ frontend/nextjs/src/components/ui/toaster.tsx | 35 +++ .../nextjs/src/components/ui/use-toast.ts | 192 +++++++++++++++ 15 files changed, 843 insertions(+), 6 deletions(-) rename frontend/nextjs/src/app/dapp/{components => _components}/providers.tsx (100%) rename frontend/nextjs/src/app/dapp/{components => _components}/right-sidebar.tsx (100%) rename frontend/nextjs/src/app/dapp/{components => _components}/sidebar.tsx (100%) create mode 100644 frontend/nextjs/src/app/dapp/p/[slug]/page.tsx create mode 100644 frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx create mode 100644 frontend/nextjs/src/app/dapp/p/create/page.tsx create mode 100644 frontend/nextjs/src/components/ui/form.tsx create mode 100644 frontend/nextjs/src/components/ui/label.tsx create mode 100644 frontend/nextjs/src/components/ui/toast.tsx create mode 100644 frontend/nextjs/src/components/ui/toaster.tsx create mode 100644 frontend/nextjs/src/components/ui/use-toast.ts diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index 465d21c..a9932e3 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -10,11 +10,14 @@ }, "dependencies": { "@auth/firebase-adapter": "^1.0.4", + "@hookform/resolvers": "^3.3.2", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toast": "^1.1.5", "@rainbow-me/rainbowkit": "^1.1.4", "@rainbow-me/rainbowkit-siwe-next-auth": "^0.3.2", "axios": "^1.6.2", @@ -30,12 +33,14 @@ "prettier": "^3.0.3", "react": "^18", "react-dom": "^18", + "react-hook-form": "^7.48.2", "react-icons": "^4.11.0", "siwe": "^2.1.4", "tailwind-merge": "^2.0.0", "tailwindcss-animate": "^1.0.7", "viem": "^1.18.1", - "wagmi": "^1.4.5" + "wagmi": "^1.4.5", + "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", diff --git a/frontend/nextjs/src/app/dapp/components/providers.tsx b/frontend/nextjs/src/app/dapp/_components/providers.tsx similarity index 100% rename from frontend/nextjs/src/app/dapp/components/providers.tsx rename to frontend/nextjs/src/app/dapp/_components/providers.tsx diff --git a/frontend/nextjs/src/app/dapp/components/right-sidebar.tsx b/frontend/nextjs/src/app/dapp/_components/right-sidebar.tsx similarity index 100% rename from frontend/nextjs/src/app/dapp/components/right-sidebar.tsx rename to frontend/nextjs/src/app/dapp/_components/right-sidebar.tsx diff --git a/frontend/nextjs/src/app/dapp/components/sidebar.tsx b/frontend/nextjs/src/app/dapp/_components/sidebar.tsx similarity index 100% rename from frontend/nextjs/src/app/dapp/components/sidebar.tsx rename to frontend/nextjs/src/app/dapp/_components/sidebar.tsx diff --git a/frontend/nextjs/src/app/dapp/layout.tsx b/frontend/nextjs/src/app/dapp/layout.tsx index 45e0338..988462d 100644 --- a/frontend/nextjs/src/app/dapp/layout.tsx +++ b/frontend/nextjs/src/app/dapp/layout.tsx @@ -5,12 +5,12 @@ import '@rainbow-me/rainbowkit/styles.css'; import { ConnectButton } from '@rainbow-me/rainbowkit'; -import { Sidebar } from './components/sidebar'; -import { RightSidebar } from './components/right-sidebar'; +import { Sidebar } from './_components/sidebar'; +import { RightSidebar } from './_components/right-sidebar'; import { Search } from '@/components/ui/forms/search'; import { Button } from '@/components/ui/button'; import { HiOutlinePencilAlt } from "react-icons/hi" -import DappProviders from './components/providers'; +import DappProviders from './_components/providers'; import SessionProvider from "@/lib/hooks/sessionProvider"; import { getServerSession } from "next-auth"; export const metadata: Metadata = { diff --git a/frontend/nextjs/src/app/dapp/p/[slug]/page.tsx b/frontend/nextjs/src/app/dapp/p/[slug]/page.tsx new file mode 100644 index 0000000..952cf0c --- /dev/null +++ b/frontend/nextjs/src/app/dapp/p/[slug]/page.tsx @@ -0,0 +1,221 @@ +import React from 'react' +import { HiCheckBadge, HiOutlineHandThumbUp, HiOutlineHandThumbDown, HiOutlineShare, HiOutlineFire } from 'react-icons/hi2' +import Image from 'next/image' +import Link from 'next/link' +import { Button } from '@/components/ui/button' +import { Card, CardHeader, CardContent, CardTitle, CardDescription, CardFooter } from '@/components/ui/card' +import { Separator } from '@/components/ui/separator' +import { Badge } from '@/components/ui/badge' +import { ScrollArea } from '@/components/ui/scroll-area' +import { RightSidebar } from '../../_components/right-sidebar' + +const Post = ({ params }: { params: { slug: string } }) => { + const post = { + title: "I’m an experienced CEO. I applied for 1001 positions. This is what happened.", + body: `Facilisi at lorem semper eget. Eget posuere dictumst velit lacus est. Fringilla quam sollicitudin diam sollicitudin magna. Arcu ullamcorper nisl at aliquet luctus. Vitae commodo dictum sed et. In ultrices eu curabitur neque pulvinar ac eget ullamcorper lorem. Velit vitae id sit gravida mi viverra. Non ipsum nunc sed risus fermentum sed in. Lectus donec dignissim diam sed non tortor. Nibh euismod id tincidunt scelerisque cras est. Tincidunt mollis commodo urna scelerisque nibh at sed. Amet odio erat congue diam in. + + Elit tellus velit diam suspendisse eget. Sed in et accumsan amet id sed ultrices lorem mollis. Donec tempus sapien pellentesque est pretium et. Ut euismod vitae feugiat donec amet euismod arcu egestas dis. Elementum neque suspendisse facilisis mi ullamcorper purus aliquam adipiscing. Sagittis non tristique sed sed purus magna sem. Integer non habitasse ornare in amet mauris id. Nulla condimentum ipsum aliquam urna vitae consequat. Nec lobortis aenean auctor imperdiet facilisis vel. Cras amet euismod neque dictumst vestibulum. Faucibus orci accumsan ipsum eget nunc magnis elit. Quam ultricies turpis scelerisque aliquet amet enim venenatis non. Iaculis hac in aliquet sed blandit vestibulum etiam. Adipiscing adipiscing augue senectus tempor. Mauris pellentesque consequat aliquet sagittis. + + In diam vestibulum eu tellus suspendisse non vestibulum. Ut ipsum risus suscipit amet quam a mi. Pellentesque est in amet in. Vitae urna laoreet non eu. Euismod ut quis elit risus massa. Posuere amet massa pulvinar cursus morbi nibh varius quam proin. Et tortor risus elementum morbi ante tortor adipiscing pretium vestibulum.`, + image: "https://images.unsplash.com/photo-1559136555-9303baea8ebd?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", + author: { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1640960543409-dbe56ccc30e2?q=80&w=1480&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D", + mentor: "true" + }, + metadata: { + upvotes: 314, + downvotes: 42 + } + } + + const topCreatorList = [ + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "false", + skill: "UI Design", + href: "/profile/naval", + ment: 134 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "Java", + href: "/profile/naval", + ment: 693 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "Ruby", + href: "/profile/naval", + ment: 953 + }, + { + name: "Naval", + avatar: "https://images.unsplash.com/photo-1607746882042-944635dfe10e?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTB8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D", + mentor: "true", + skill: "AI", + href: "/profile/naval", + ment: 422 + }, + ] + + return ( +
+
+ + + +
+
+ {`${post.author.name}-avatar`} +
+
+
+

{post.author.name}

+ {post.author.mentor === "true" && } +
20 secs. ago
+
+ +
+
+ +
+ +
+ {`${post.title} +
+ {post.title} + {post.body} +
+ + + +
+
+ +
+ {post.metadata.upvotes} +
+ +
+
+ +
+
+ + +
+
+
+
+ + <> + +
+

+ Top Creators +

+
+ {topCreatorList.map((profile, key) => { + return +
+
+ {`${profile.name}-avatar`} +
+
+
+

{profile.name}

+ {profile.mentor === "true" && } +
+ {profile.skill} +
+
+
+ +
+ 245 MENT +
+
+ + })} + + +
+
+ +
+

+ Who to Follow +

+
+ {topCreatorList.map((profile, key) => { + return +
+
+ {`${profile.name}-avatar`} +
+
+
+

{profile.name}

+ {profile.mentor === "true" && } +
+ {profile.skill} +
+
+
+ +
+ 245 MENT +
+
+ + })} + + +
+
+ +
+
+ ) +} + +export default Post \ No newline at end of file diff --git a/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx b/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx new file mode 100644 index 0000000..73f6a0a --- /dev/null +++ b/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx @@ -0,0 +1,27 @@ +"use client" +import React from 'react' +import * as z from "zod" + +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { toast } from "@/components/ui/use-toast" + +const CreatePostForm = () => { + const formSchema = z.object({ + username: z.string().min(2).max(50), + }) + return ( +
CreatePostForm
+ ) +} + +export default CreatePostForm \ No newline at end of file diff --git a/frontend/nextjs/src/app/dapp/p/create/page.tsx b/frontend/nextjs/src/app/dapp/p/create/page.tsx new file mode 100644 index 0000000..79a198f --- /dev/null +++ b/frontend/nextjs/src/app/dapp/p/create/page.tsx @@ -0,0 +1,28 @@ +import React from 'react' +import { HiCheckBadge, HiOutlineHandThumbUp, HiOutlineHandThumbDown, HiOutlineShare, HiOutlineFire } from 'react-icons/hi2' +import Image from 'next/image' +import Link from 'next/link' +import { Button } from '@/components/ui/button' +import { Card, CardHeader, CardContent, CardTitle, CardDescription, CardFooter } from '@/components/ui/card' +import { Separator } from '@/components/ui/separator' +import { Badge } from '@/components/ui/badge' +import { ScrollArea } from '@/components/ui/scroll-area' +import { RightSidebar } from '../../_components/right-sidebar' + +const CreatePost = () => { + + return ( +
+
+ +

New Post

+
+
+ + {/* leave empty */} + +
+ ) +} + +export default CreatePost \ No newline at end of file diff --git a/frontend/nextjs/src/app/dapp/page.tsx b/frontend/nextjs/src/app/dapp/page.tsx index 3e2f678..29fc83c 100644 --- a/frontend/nextjs/src/app/dapp/page.tsx +++ b/frontend/nextjs/src/app/dapp/page.tsx @@ -6,7 +6,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import PostCard from "@/components/ui/post-card"; import { Separator } from "@/components/ui/separator"; import { ScrollArea } from "@/components/ui/scroll-area"; -import { RightSidebar } from "./components/right-sidebar"; +import { RightSidebar } from "./_components/right-sidebar"; import Image from "next/image"; import { HiCheckBadge, HiOutlineFire } from "react-icons/hi2" import { Badge } from "@/components/ui/badge"; diff --git a/frontend/nextjs/src/components/ui/form.tsx b/frontend/nextjs/src/components/ui/form.tsx new file mode 100644 index 0000000..4603f8b --- /dev/null +++ b/frontend/nextjs/src/components/ui/form.tsx @@ -0,0 +1,176 @@ +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, +} from "react-hook-form" + +import { cn } from "@/lib/utils" +import { Label } from "@/components/ui/label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +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 ") + } + + 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 +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId() + + return ( + +
+ + ) +}) +FormItem.displayName = "FormItem" + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField() + + return ( +
@@ -77,7 +78,6 @@ const PostCard = ({data}: any) => { - ) } diff --git a/frontend/nextjs/src/components/ui/toast.tsx b/frontend/nextjs/src/components/ui/toast.tsx new file mode 100644 index 0000000..a822477 --- /dev/null +++ b/frontend/nextjs/src/components/ui/toast.tsx @@ -0,0 +1,127 @@ +import * as React from "react" +import * as ToastPrimitives from "@radix-ui/react-toast" +import { cva, type VariantProps } from "class-variance-authority" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const ToastProvider = ToastPrimitives.Provider + +const ToastViewport = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastViewport.displayName = ToastPrimitives.Viewport.displayName + +const toastVariants = cva( + "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", + { + variants: { + variant: { + default: "border bg-background text-foreground", + destructive: + "destructive group border-destructive bg-destructive text-destructive-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Toast = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, ...props }, ref) => { + return ( + + ) +}) +Toast.displayName = ToastPrimitives.Root.displayName + +const ToastAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastAction.displayName = ToastPrimitives.Action.displayName + +const ToastClose = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +ToastClose.displayName = ToastPrimitives.Close.displayName + +const ToastTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastTitle.displayName = ToastPrimitives.Title.displayName + +const ToastDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ToastDescription.displayName = ToastPrimitives.Description.displayName + +type ToastProps = React.ComponentPropsWithoutRef + +type ToastActionElement = React.ReactElement + +export { + type ToastProps, + type ToastActionElement, + ToastProvider, + ToastViewport, + Toast, + ToastTitle, + ToastDescription, + ToastClose, + ToastAction, +} diff --git a/frontend/nextjs/src/components/ui/toaster.tsx b/frontend/nextjs/src/components/ui/toaster.tsx new file mode 100644 index 0000000..e223385 --- /dev/null +++ b/frontend/nextjs/src/components/ui/toaster.tsx @@ -0,0 +1,35 @@ +"use client" + +import { + Toast, + ToastClose, + ToastDescription, + ToastProvider, + ToastTitle, + ToastViewport, +} from "@/components/ui/toast" +import { useToast } from "@/components/ui/use-toast" + +export function Toaster() { + const { toasts } = useToast() + + return ( + + {toasts.map(function ({ id, title, description, action, ...props }) { + return ( + +
+ {title && {title}} + {description && ( + {description} + )} +
+ {action} + +
+ ) + })} + +
+ ) +} diff --git a/frontend/nextjs/src/components/ui/use-toast.ts b/frontend/nextjs/src/components/ui/use-toast.ts new file mode 100644 index 0000000..90d8959 --- /dev/null +++ b/frontend/nextjs/src/components/ui/use-toast.ts @@ -0,0 +1,192 @@ +// Inspired by react-hot-toast library +import * as React from "react" + +import type { + ToastActionElement, + ToastProps, +} from "@/components/ui/toast" + +const TOAST_LIMIT = 1 +const TOAST_REMOVE_DELAY = 1000000 + +type ToasterToast = ToastProps & { + id: string + title?: React.ReactNode + description?: React.ReactNode + action?: ToastActionElement +} + +const actionTypes = { + ADD_TOAST: "ADD_TOAST", + UPDATE_TOAST: "UPDATE_TOAST", + DISMISS_TOAST: "DISMISS_TOAST", + REMOVE_TOAST: "REMOVE_TOAST", +} as const + +let count = 0 + +function genId() { + count = (count + 1) % Number.MAX_VALUE + return count.toString() +} + +type ActionType = typeof actionTypes + +type Action = + | { + type: ActionType["ADD_TOAST"] + toast: ToasterToast + } + | { + type: ActionType["UPDATE_TOAST"] + toast: Partial + } + | { + type: ActionType["DISMISS_TOAST"] + toastId?: ToasterToast["id"] + } + | { + type: ActionType["REMOVE_TOAST"] + toastId?: ToasterToast["id"] + } + +interface State { + toasts: ToasterToast[] +} + +const toastTimeouts = new Map>() + +const addToRemoveQueue = (toastId: string) => { + if (toastTimeouts.has(toastId)) { + return + } + + const timeout = setTimeout(() => { + toastTimeouts.delete(toastId) + dispatch({ + type: "REMOVE_TOAST", + toastId: toastId, + }) + }, TOAST_REMOVE_DELAY) + + toastTimeouts.set(toastId, timeout) +} + +export const reducer = (state: State, action: Action): State => { + switch (action.type) { + case "ADD_TOAST": + return { + ...state, + toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), + } + + case "UPDATE_TOAST": + return { + ...state, + toasts: state.toasts.map((t) => + t.id === action.toast.id ? { ...t, ...action.toast } : t + ), + } + + case "DISMISS_TOAST": { + const { toastId } = action + + // ! Side effects ! - This could be extracted into a dismissToast() action, + // but I'll keep it here for simplicity + if (toastId) { + addToRemoveQueue(toastId) + } else { + state.toasts.forEach((toast) => { + addToRemoveQueue(toast.id) + }) + } + + return { + ...state, + toasts: state.toasts.map((t) => + t.id === toastId || toastId === undefined + ? { + ...t, + open: false, + } + : t + ), + } + } + case "REMOVE_TOAST": + if (action.toastId === undefined) { + return { + ...state, + toasts: [], + } + } + return { + ...state, + toasts: state.toasts.filter((t) => t.id !== action.toastId), + } + } +} + +const listeners: Array<(state: State) => void> = [] + +let memoryState: State = { toasts: [] } + +function dispatch(action: Action) { + memoryState = reducer(memoryState, action) + listeners.forEach((listener) => { + listener(memoryState) + }) +} + +type Toast = Omit + +function toast({ ...props }: Toast) { + const id = genId() + + const update = (props: ToasterToast) => + dispatch({ + type: "UPDATE_TOAST", + toast: { ...props, id }, + }) + const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) + + dispatch({ + type: "ADD_TOAST", + toast: { + ...props, + id, + open: true, + onOpenChange: (open) => { + if (!open) dismiss() + }, + }, + }) + + return { + id: id, + dismiss, + update, + } +} + +function useToast() { + const [state, setState] = React.useState(memoryState) + + React.useEffect(() => { + listeners.push(setState) + return () => { + const index = listeners.indexOf(setState) + if (index > -1) { + listeners.splice(index, 1) + } + } + }, [state]) + + return { + ...state, + toast, + dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), + } +} + +export { useToast, toast } From bf9f22320630a2910b586f12f9b70fd82c091353 Mon Sep 17 00:00:00 2001 From: Odafe Aror Date: Thu, 16 Nov 2023 16:05:38 +0000 Subject: [PATCH 14/15] add screen to create a post --- frontend/nextjs/package.json | 5 + .../p/create/_components/create-post-form.tsx | 82 +++++++++++++--- .../nextjs/src/app/dapp/p/create/page.tsx | 4 +- frontend/nextjs/src/app/dapp/profile/page.tsx | 9 ++ frontend/nextjs/src/app/layout.tsx | 2 + frontend/nextjs/src/components/ui/form.tsx | 2 +- frontend/nextjs/src/components/ui/input.tsx | 2 +- .../src/components/ui/rich-text-editor.tsx | 42 ++++++++ .../nextjs/src/components/ui/textarea.tsx | 24 +++++ frontend/nextjs/src/components/ui/toggle.tsx | 45 +++++++++ frontend/nextjs/src/components/ui/toolbar.tsx | 97 +++++++++++++++++++ 11 files changed, 300 insertions(+), 14 deletions(-) create mode 100644 frontend/nextjs/src/app/dapp/profile/page.tsx create mode 100644 frontend/nextjs/src/components/ui/rich-text-editor.tsx create mode 100644 frontend/nextjs/src/components/ui/textarea.tsx create mode 100644 frontend/nextjs/src/components/ui/toggle.tsx create mode 100644 frontend/nextjs/src/components/ui/toolbar.tsx diff --git a/frontend/nextjs/package.json b/frontend/nextjs/package.json index a9932e3..382d583 100644 --- a/frontend/nextjs/package.json +++ b/frontend/nextjs/package.json @@ -18,8 +18,13 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", "@rainbow-me/rainbowkit": "^1.1.4", "@rainbow-me/rainbowkit-siwe-next-auth": "^0.3.2", + "@tiptap/extension-placeholder": "^2.1.12", + "@tiptap/pm": "^2.1.12", + "@tiptap/react": "^2.1.12", + "@tiptap/starter-kit": "^2.1.12", "axios": "^1.6.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", diff --git a/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx b/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx index 73f6a0a..83cbf49 100644 --- a/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx +++ b/frontend/nextjs/src/app/dapp/p/create/_components/create-post-form.tsx @@ -1,26 +1,86 @@ "use client" import React from 'react' import * as z from "zod" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" import { Button } from "@/components/ui/button" import { - Form, - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" -import { toast } from "@/components/ui/use-toast" +import { useToast } from "@/components/ui/use-toast" +import { Textarea } from "@/components/ui/textarea" +import RichTextEditor from '@/components/ui/rich-text-editor' + +const formSchema = z.object({ + postTitle: z.string().min(1, { + message: "Title can't be empty", + }), + postBody: z.string() +}) const CreatePostForm = () => { - const formSchema = z.object({ - username: z.string().min(2).max(50), + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + postTitle: "", + postBody: "", + }, }) + const { toast } = useToast() + + function onSubmit(values: z.infer) { + console.log(values) + toast({ + description: "Your post has been created", + + }) + } + return ( -
CreatePostForm
+
+
+ + ( + + Title + + + + + + )} + /> + + ( + + Body + + + + + + )} + /> +
+ +
+ + +
) } diff --git a/frontend/nextjs/src/app/dapp/p/create/page.tsx b/frontend/nextjs/src/app/dapp/p/create/page.tsx index 79a198f..49cd8b2 100644 --- a/frontend/nextjs/src/app/dapp/p/create/page.tsx +++ b/frontend/nextjs/src/app/dapp/p/create/page.tsx @@ -8,6 +8,7 @@ import { Separator } from '@/components/ui/separator' import { Badge } from '@/components/ui/badge' import { ScrollArea } from '@/components/ui/scroll-area' import { RightSidebar } from '../../_components/right-sidebar' +import CreatePostForm from './_components/create-post-form' const CreatePost = () => { @@ -15,7 +16,8 @@ const CreatePost = () => {
-

New Post

+

New Post

+
diff --git a/frontend/nextjs/src/app/dapp/profile/page.tsx b/frontend/nextjs/src/app/dapp/profile/page.tsx new file mode 100644 index 0000000..f52d50d --- /dev/null +++ b/frontend/nextjs/src/app/dapp/profile/page.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +const Profile = () => { + return ( +
Profile
+ ) +} + +export default Profile \ No newline at end of file diff --git a/frontend/nextjs/src/app/layout.tsx b/frontend/nextjs/src/app/layout.tsx index 5fe0568..77b28ec 100644 --- a/frontend/nextjs/src/app/layout.tsx +++ b/frontend/nextjs/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from 'next' import { Inter } from 'next/font/google' import './globals.css' import { ThemeProvider } from '@/components/ui/theme-provider' +import { Toaster } from "@/components/ui/toaster" const inter = Inter({ subsets: ["latin"] }); @@ -28,6 +29,7 @@ export default async function RootLayout({ disableTransitionOnChange > {children} + diff --git a/frontend/nextjs/src/components/ui/form.tsx b/frontend/nextjs/src/components/ui/form.tsx index 4603f8b..3aa0c7c 100644 --- a/frontend/nextjs/src/components/ui/form.tsx +++ b/frontend/nextjs/src/components/ui/form.tsx @@ -93,7 +93,7 @@ const FormLabel = React.forwardRef< return (