diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 534600b..f7f8e8d 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,17 +2,13 @@ import type { Metadata } from 'next' import { Bai_Jamjuree as FontSans } from 'next/font/google' import './globals.css' import 'react-toastify/dist/ReactToastify.css' - import { cn } from '@/lib/utils' - import { headers } from 'next/headers' - import { cookieToInitialState } from 'wagmi' import Providers from '@/lib/providers' import { config } from '@/lib/wagmi' import AppKitProvider from '@/lib/providers' - const fontSans = FontSans({ subsets: ['latin'], weight: ['400', '700'], @@ -20,12 +16,14 @@ const fontSans = FontSans({ }) export const metadata: Metadata = { title: 'Studio | MyriadFlow', - description: 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', + description: + 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', openGraph: { type: 'website', url: 'https://studio.myriadflow.com', title: 'Studio | MyriadFlow', - description: 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', + description: + 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', images: [ { url: '/metaimg.png', @@ -39,7 +37,8 @@ export const metadata: Metadata = { card: 'summary_large_image', site: '@MyriadFlow', title: 'Studio | MyriadFlow', - description: 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', + description: + 'Bring your brand to the future! MyriadFlow Studio empowers you to launch and manage brands, collections, and phygital NFTs with WebXR experiences – all without coding.', images: [ { url: '/metaimg.png', @@ -66,7 +65,9 @@ export default function RootLayout({ fontSans.variable )} > - {children} + + {children} + diff --git a/src/app/page.tsx b/src/app/page.tsx index ada6883..be66cd8 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,302 +4,323 @@ import { Button, Navbar } from '@/components' import Image from 'next/image' import Link from 'next/link' import { useAccount } from 'wagmi' + import { toast, ToastContainer } from 'react-toastify' import Footer from '@/components/footer' -import { v4 as uuidv4 } from 'uuid'; +import { v4 as uuidv4 } from 'uuid' interface Brand { - id: string; // UUID type - logo_image: string; - name: string; - description: string; + id: string // UUID type + logo_image: string + name: string + description: string } export default function Home() { - const { address: walletAddress } = useAccount() - const [hasAddress, setHasAddress] = useState(false); - const [brands, setBrands] = useState([]); - const [showForm, setShowForm] = useState(false); - const account = useAccount() - const [displayName, setDisplayName] = useState(''); - const [email, setEmail] = useState(''); - const [tosChecked, setTosChecked] = useState(false); - const [newsletterChecked, setNewsletterChecked] = useState(false); - - const apiUrl = process.env.NEXT_PUBLIC_URI; - const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com'; - + const { address: walletAddress } = useAccount() + const [hasAddress, setHasAddress] = useState(false) + const [brands, setBrands] = useState([]) + const [showForm, setShowForm] = useState(false) + const account = useAccount() + const [displayName, setDisplayName] = useState('') + const [email, setEmail] = useState('') + const [tosChecked, setTosChecked] = useState(false) + const [newsletterChecked, setNewsletterChecked] = useState(false) - useEffect(() => { - const checkEmailExists = async () => { - if (account?.address) { - try { - const response = await fetch(`${baseUri}/profiles/email/${account.address}`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }); + const apiUrl = process.env.NEXT_PUBLIC_URI + const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' - if (response.ok) { - const data = await response.json(); - console.log(data.email); + useEffect(() => { + const checkEmailExists = async () => { + if (account?.address) { + try { + const response = await fetch( + `${baseUri}/profiles/email/${account.address}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + } + ) - // If the email exists, set showForm to false - if (data.email) { - setShowForm(false); - } else { - setShowForm(true); - } - } else { - // Handle errors or cases where no data is returned - setShowForm(true); - } - } catch (error) { - console.error('Error fetching profile data:', error); - setShowForm(true); - } - } - }; + if (response.ok) { + const data = await response.json() + console.log(data.email) - checkEmailExists(); - }, [account.address]); + // If the email exists, set showForm to false + if (data.email) { + setShowForm(false) + } else { + setShowForm(true) + } + } else { + // Handle errors or cases where no data is returned + setShowForm(true) + } + } catch (error) { + console.error('Error fetching profile data:', error) + setShowForm(true) + } + } + } + checkEmailExists() + }, [account.address]) - const handleSubmit = async () => { - if (displayName && email && tosChecked) { - try { - const profileId = uuidv4(); - const response = await fetch(`${baseUri}/profiles`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - id: profileId, - name: displayName, - email: email, - wallet_address: account.address, - chaintype_id: '554b4903-9a06-4031-98f4-48276c427f78' - }), - }); + const handleSubmit = async () => { + if (displayName && email && tosChecked) { + try { + const profileId = uuidv4() + const response = await fetch(`${baseUri}/profiles`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + id: profileId, + name: displayName, + email: email, + wallet_address: account.address, + chaintype_id: '554b4903-9a06-4031-98f4-48276c427f78', + }), + }) - if (response.ok) { - setShowForm(false); - } else { - console.error('Failed to submit profile data'); - } - } catch (error) { - console.error('Error submitting profile data:', error); - } - } - }; - const getBrands = async () => { - try { - const res = await fetch(`${apiUrl}/brands/manager/${walletAddress}`) - if (!res.ok) { - throw new Error('Network response was not ok'); - } - const result: Brand[] = await res.json(); - setBrands(result); - } catch (error) { - console.error('Failed to fetch brands:', error); - } - } + if (response.ok) { + setShowForm(false) + } else { + console.error('Failed to submit profile data') + } + } catch (error) { + console.error('Error submitting profile data:', error) + } + } + } + const getBrands = async () => { + try { + const res = await fetch(`${apiUrl}/brands/manager/${walletAddress}`) + if (!res.ok) { + throw new Error('Network response was not ok') + } + const result: Brand[] = await res.json() + setBrands(result) + } catch (error) { + console.error('Failed to fetch brands:', error) + } + } - useEffect(() => { - if (walletAddress) { - localStorage.setItem("walletAddress", walletAddress); - localStorage.setItem("BaseSepoliaChain", "554b4903-9a06-4031-98f4-48276c427f78") - setHasAddress(true); - getBrands(); - } else { - setHasAddress(false); - } - }, [walletAddress]); + useEffect(() => { + if (walletAddress) { + localStorage.setItem('walletAddress', walletAddress) + localStorage.setItem( + 'BaseSepoliaChain', + '554b4903-9a06-4031-98f4-48276c427f78' + ) + setHasAddress(true) + getBrands() + } else { + setHasAddress(false) + } + }, [walletAddress]) - const ifConnected = async () => { - if (!walletAddress) { - toast.warning('Connect your wallet'); - } - } + const ifConnected = async () => { + if (!walletAddress) { + toast.warning('Connect your wallet') + } + } - return ( - <> - -
- - {/* + +
+ + {/* blob */} - {hasAddress ? ( -
-
- - - -
- {brands.length == 0 && ( -
-

- Myriadflow studio -

-

- - Welcome to MyriadFlow Studio, your one-stop shop for creating groundbreaking phygital NFTs! -

-
-

- You have not created any brands yet. Ready to start your journey? -

- - - -
-
- )} - {showForm && ( -
-
-

- You're almost ready! -

-

- Choose a public display name and share your email address to sign up with MyriadFlow. -

+ {hasAddress ? ( +
+
+ + + +
+ {brands.length == 0 && ( +
+

+ Myriadflow studio +

+

+ + Welcome to MyriadFlow Studio, your one-stop shop for + creating groundbreaking phygital NFTs! + +

+
+

+ You have not created any brands yet. Ready to start your + journey? +

+ + + +
+
+ )} + {showForm && ( +
+
+

+ You're almost ready! +

+

+ Choose a public display name and share your email address to + sign up with MyriadFlow. +

- setDisplayName(e.target.value)} - className="w-full p-2 mb-2 rounded-lg border border-gray-300 mt-4" - required - /> - setEmail(e.target.value)} - className="w-full p-2 mb-2 rounded-md border border-gray-300" - required - /> -
- setTosChecked(e.target.checked)} - className="mr-2 -mt-4" - required - /> - -
-
- setNewsletterChecked(e.target.checked)} - className="mr-2 -mt-4" - /> - -
- - -
-
- )} -
- {brands.map((brand) => ( - // -
- {brand.name} -

{brand.name}

-

{brand.description}

-
- //
- ))} -
-
- ) : ( -
-

- Myriadflow studio -

-

- - Welcome to MyriadFlow Studio, your one-stop shop for creating groundbreaking phygital NFTs! -

-
-

- You have not created any brands yet. Ready to start your journey? -

- -
-
- )} - {/* setDisplayName(e.target.value)} + className='w-full p-2 mb-2 rounded-lg border border-gray-300 mt-4' + required + /> + setEmail(e.target.value)} + className='w-full p-2 mb-2 rounded-md border border-gray-300' + required + /> +
+ setTosChecked(e.target.checked)} + className='mr-2 -mt-4' + required + /> + +
+
+ setNewsletterChecked(e.target.checked)} + className='mr-2 -mt-4' + /> + +
+ + +
+
+ )} +
+ {brands.map((brand) => ( + // +
+ {brand.name} +

{brand.name}

+

{brand.description}

+
+ //
+ ))} +
+
+ ) : ( +
+

+ Myriadflow studio +

+

+ + Welcome to MyriadFlow Studio, your one-stop shop for creating + groundbreaking phygital NFTs! + +

+
+

+ You have not created any brands yet. Ready to start your + journey? +

+ +
+
+ )} + {/* blob */} -
-
- - ) +
+
+ + ) } diff --git a/src/components/ui/navbar.tsx b/src/components/ui/navbar.tsx index 8d85737..a6a0d27 100644 --- a/src/components/ui/navbar.tsx +++ b/src/components/ui/navbar.tsx @@ -1,4 +1,4 @@ -"use client"; +'use client' import { NavigationMenu, NavigationMenuItem, @@ -7,72 +7,97 @@ import { import { Logo } from './logo' import { Button } from './button' import { toast, ToastContainer } from 'react-toastify' -import { useAccount, useDisconnect } from 'wagmi' -import React, { useState, useEffect } from "react"; -import { usePathname } from "next/navigation" +import { useAccount, useDisconnect, useConnect } from 'wagmi' +import React, { useState, useEffect } from 'react' +import { usePathname } from 'next/navigation' import Link from 'next/link' +import { injected } from 'wagmi/connectors' export const Navbar = () => { - const [isDropdownOpen, setIsDropdownOpen] = useState(false); - const { address } = useAccount(); - const { disconnect } = useDisconnect(); - const pathname = usePathname(); - const [name, setName] = useState(''); - const [profileImage, setProfileImage] = useState(''); - const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com'; + const [isDropdownOpen, setIsDropdownOpen] = useState(false) + + const { disconnect } = useDisconnect() + const { isConnected, address } = useAccount() + const { connect } = useConnect() + const pathname = usePathname() + const [name, setName] = useState('') + const [profileImage, setProfileImage] = useState('') + const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' + + useEffect(() => { + // Check for saved wallet address in localStorage + const savedAddress = localStorage.getItem('walletAddress') + + if (savedAddress) { + // Automatically connect if there's an address saved and not currently connected + if (!isConnected) { + connect({ connector: injected() }) + } + } + + // Manage session details in localStorage based on connection status + if (isConnected && !savedAddress) { + // Store session details in localStorage + localStorage.setItem('walletAddress', address!) + } + }, [connect, isConnected, address]) useEffect(() => { const getUserData = async () => { if (address) { try { - const response = await fetch(`${baseUri}/profiles/wallet/${address}`, { - method: 'GET', - headers: { - 'content-Type': 'application/json', - }, - }); + const response = await fetch( + `${baseUri}/profiles/wallet/${address}`, + { + method: 'GET', + headers: { + 'content-Type': 'application/json', + }, + } + ) if (response.ok) { - const data = await response.json(); - setName(data.name); - setProfileImage(data.profile_image); + const data = await response.json() + setName(data.name) + setProfileImage(data.profile_image) } else { - console.log('No user found'); + console.log('No user found') } } catch (error) { - console.error('Error fetching user data', error); + console.error('Error fetching user data', error) } } - }; - getUserData(); - }, [address]); + } + getUserData() + }, [address]) const navlinks = [ { title: 'Home', path: 'https://myriadflow.com' }, { title: 'Discover', path: 'https://discover.myriadflow.com' }, { title: 'Studio', path: 'https://studio.myriadflow.com' }, { title: 'WebXR', path: 'https://webxr.myriadflow.com' }, - ]; + ] const Notification = () => { if (!address) { - toast.warning("Currently works with Metamask and Coinbase Wallet Extension. We are working on Smart Wallet functionality.", { - containerId: "containerA", - position: 'top-left', - } + toast.warning( + 'Currently works with Metamask and Coinbase Wallet Extension. We are working on Smart Wallet functionality.', + { + containerId: 'containerA', + position: 'top-left', + } ) } - }; + } const handleLogout = () => { - disconnect(); - }; - + localStorage.removeItem('walletAddress') + disconnect() + } return ( <> - - + @@ -81,86 +106,134 @@ export const Navbar = () => { {link.title} ))} -
+
{address ? ( <> {/* User Section */} -
+
{isDropdownOpen && (
- -
+
Profile -
- {name} - +
+ + {name} + + View profile
- - + My assets - + On sale - + My brands - + My collections - + Activity - + Rewards - + Create - + Profile Settings {/* Wallet Address */} -
+
{address}
{/* Separator */} -
+
{/* Logout Button */}
)} -
) : ( @@ -171,8 +244,10 @@ export const Navbar = () => {
- + - ) }