initial commit

This commit is contained in:
=Mtg_Dev
2021-11-16 22:04:55 +02:00
parent 5534632d5b
commit eaad4f2ffe
35 changed files with 3220 additions and 98 deletions

View File

@@ -0,0 +1,51 @@
import { motion } from "framer-motion";
import { ModalCard, modalCardVariants } from "../Shared/Modal/Modal";
interface Props extends ModalCard {
}
export default function Step1({ onClose, direction }: Props) {
return (
<motion.div
custom={direction}
variants={modalCardVariants}
initial={'initial'}
animate="animate"
exit='exit'
className="rounded-[40px] bg-gray-50 overflow-hidden w-full"
>
<div className="p-24">
<div className="flex gap-24 items-center">
<div className="flex-shrink-0 w-[93px] h-[93px] rounded-md overflow-hidden">
<img className="w-full h-full object-cover" src="https://s3-alpha-sig.figma.com/img/be1b/cd75/1baa911b3875134c0889d6755c4ba2cb?Expires=1637539200&Signature=QExmgJCGGSES~zIwM-2G8yd7aPR-j5eFnV3tOg6BkSdXVB9AMhHQPbRpbfOv~rD3hdMdSPMkS9kfjyFbAuonltV2zrf5GOwGxrF2GVdhpIGc6RiqGLWVVY8mXysEm6~0fVj~2SK8hec~YnV1h0oHDQiZF5YjGi143pImGmcVERPpB7MiksSoD0Vki6RXamySopj~f-~lUGy2uKRbQKxQ4LCFTz-H9O8vpkZpCVq274FYsqsEtUihwVjniNXV8ukLxdL~rfgf8L9MeiR7gDYYQ9MSLMZKEa~TnQ-JadlngQz78a2T801WaG2xp5hGHYQMtIi1ES-N4FOg5PwEjtIetA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA" alt="" />
</div>
<div>
<h3 className="text-h3 font-regular">Project Name</h3>
<a className="text-blue-400 font-regular text-body4" href="/">www.project.com</a>
</div>
<div className="flex ml-auto gap-16">
<button className="btn btn-primary py-12 px-24 rounded-lg my-16">Play 🕹</button>
<button className="btn py-12 px-24 rounded-lg my-16">Vote 🔥</button>
</div>
</div>
<p className="mt-40 text-body4 leading-normal">Lorem ipsum dolor, sit amet consectetur adipisicing elit. At natus perferendis sunt suscipit libero amet praesentium? Magni minus libero maxime aspernatur eius, repudiandae distinctio aut perferendis laboriosam impedit reiciendis blanditiis cum alias hic, ipsam facere obcaecati, amet atque numquam doloribus in explicabo possimus autem! Ipsum consequatur, dignissimos minima esse illum obcaecati aliquid eligendi delectus architecto beatae perferendis. Ipsam, non maxime.</p>
<div className="flex gap-24 mt-24 flex-wrap">
<span className="chip-small bg-red-100 text-red-800 font-regular"> payments </span>
<span className="chip-small bg-primary-100 text-primary-800 font-regular"> lightining </span>
</div>
<div className="mt-40">
<h3 className="text-h5 font-bold">Screen Shots</h3>
<div className="flex gap-x-24 gap-y-20">
<div className="flex-none w-[164px] h-[120px] md:w-[300px] md:h-[136px] bg-gray-300 rounded-xl"></div>
<div className="flex-none w-[164px] h-[120px] md:w-[300px] md:h-[136px] bg-gray-300 rounded-xl"></div>
<div className="flex-none w-[164px] h-[120px] md:w-[300px] md:h-[136px] bg-gray-300 rounded-xl"></div>
</div>
</div>
</div>
</motion.div>
)
}

View File

@@ -0,0 +1,16 @@
import Categories from "./partials/Categories";
import Header from "./partials/Header";
import ProjectsSection from "./partials/ProjectsSection";
export default function ExplorePage() {
return (
<div className='px-32'>
<Header />
<div className="my-40">
<Categories />
</div>
<ProjectsSection />
</div>
)
}

View File

@@ -0,0 +1,20 @@
import { getAllCategories } from "../../../api"
import { useQuery } from 'react-query'
export default function Categories() {
const { data, isLoading } = useQuery("categories", getAllCategories);
const handleClick = (categoryId: string) => {
}
if (isLoading)
return null;
return (
<div className="flex gap-12 flex-wrap">
{data?.map(category => <span key={category.id} className="chip hover:cursor-pointer hover:bg-gray-200" onClick={() => handleClick(category.id)}>{category.title}</span>)}
</div>
)
}

View File

@@ -0,0 +1,56 @@
const headerLinks = [
{
title: "A fun directory of Lightning Enabled Applications on the Open Web",
img:
"https://s3-alpha-sig.figma.com/img/07b8/5d84/145942255afd215b3da26dbbf1dd03bd?Expires=1638144000&Signature=Cl1DUQJIUsrrFi48M~qU1r3Z0agGdy-uiNUao5g8-nu34QtoyWTFPXvaH3naSZBYqcPyKFq1jaXF6Mw1uj1hdWwGhXhMPLnKNJFFrGViVXhXu-3YeCPY9p4-IcieFJBZPVA~zDY8zxY5b06loWsINAVx4eMHRAhSWl~~Mca5PjlSXloiYrT00W-6c9m8gevfMMX~PsHQedzwYzg0j2DlnhPX8LbRkli1G2OxtCaFwo3~HGHXIlFGuGU1uXRvi1qBWrdjdsuWgIly1ekcFfJWAKmwYXk06EtCmfWRgGYbD7cBK~lwOkFofbf1LW0yqLv0hr4svwToH~3FiHenrCF-1g__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
link: {
content: "Submit App",
url: "#",
},
},
{
title:
"Join the next wave of the Lightning Network in Novembers Shock the Web hackathon",
img: 'https://s3-alpha-sig.figma.com/img/be1b/cd75/1baa911b3875134c0889d6755c4ba2cb?Expires=1637539200&Signature=QExmgJCGGSES~zIwM-2G8yd7aPR-j5eFnV3tOg6BkSdXVB9AMhHQPbRpbfOv~rD3hdMdSPMkS9kfjyFbAuonltV2zrf5GOwGxrF2GVdhpIGc6RiqGLWVVY8mXysEm6~0fVj~2SK8hec~YnV1h0oHDQiZF5YjGi143pImGmcVERPpB7MiksSoD0Vki6RXamySopj~f-~lUGy2uKRbQKxQ4LCFTz-H9O8vpkZpCVq274FYsqsEtUihwVjniNXV8ukLxdL~rfgf8L9MeiR7gDYYQ9MSLMZKEa~TnQ-JadlngQz78a2T801WaG2xp5hGHYQMtIi1ES-N4FOg5PwEjtIetA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA', link: {
content: "Register Now",
url: "#",
},
},
];
export default function Header() {
return (
<div className="flex gap-40 justify-center md:justify-between">
<div className="flex-grow rounded-20 h-[280px] relative overflow-hidden p-24 flex flex-col items-start justify-end">
<img
className="w-full h-full object-cover absolute top-0 left-0 z-[-2]"
src={headerLinks[0].img}
alt=""
/>
<div className="w-full h-full object-cover bg-black opacity-40 absolute top-0 left-0 z-[-1]"></div>
<h3 className="text-white text-h3 max-w-md">{headerLinks[0].title}</h3>
<a
href={headerLinks[0].link.url}
className="btn btn-primary font-regular mt-36"
>
{headerLinks[0].link.content}
</a>
</div>
<div className="hidden flex-grow rounded-20 h-[280px] relative overflow-hidden p-24 md:flex flex-col items-start justify-end">
<img
className="w-full h-full object-cover absolute top-0 left-0 z-[-2]"
src={headerLinks[1].img}
alt=""
/>
<div className="w-full h-full object-cover bg-black opacity-40 absolute top-0 left-0 z-[-1]"></div>
<h3 className="text-white text-h3 max-w-md">
{headerLinks[1].title}
</h3>
<a href={headerLinks[1].link.url} className="btn font-regular mt-36">
{headerLinks[1].link.content}
</a>
</div>
</div>
);
}

View File

@@ -0,0 +1,56 @@
import { ReactElement, useRef } from "react";
import { ProjectCard } from "../../../utils/interfaces";
import Carousel from 'react-multi-carousel';
import { MdLocalFireDepartment } from 'react-icons/md';
import { useAppDispatch } from "../../../utils/hooks";
import { ModalId, openModal } from "../../../redux/features/modals.slice";
const responsive = {
all: {
breakpoint: { max: 5000, min: 0 },
items: (((window.innerWidth - 64) / (296 + 24))),
}
}
interface Props { title: string | ReactElement, projects: ProjectCard[] }
export default function ProjectsRow({ title, projects }: Props) {
const dispatch = useAppDispatch()
let drag = useRef(false);
document.addEventListener('mousedown', () => drag.current = false);
document.addEventListener('mousemove', () => drag.current = true);
const handleClick = (projectId: string) => {
projectId = '123123123';
if (!drag.current)
dispatch(openModal({ modalId: ModalId.Project, initialModalProps: { projectId } }))
}
return (
<div className='mb-40 overflow-hidden'>
<h3 className="font-bolder text-body3 mb-20">{title}</h3>
<Carousel
className='py-10'
showDots={false}
arrows={false}
responsive={responsive}
>
{projects.map((project, idx) => <div key={idx} className="select-none px-16 py-16 flex w-[296px] gap-16 border-gray-100 shadow-md border-2 rounded-10 transform transition-transform hover:cursor-pointer hover:scale-105" onClick={() => handleClick(project.id)}>
<img src={project.img} draggable="false" className="flex-shrink-0 w-80 h-80 bg-gray-200 border-0 rounded-8"></img>
<div className="justify-around items-start min-w-0">
<p className="text-body4 w-full font-bold overflow-ellipsis overflow-hidden whitespace-nowrap">{project.title}</p>
<p className="text-body5 text-gray-600 font-light my-[5px]">{project.category.title}</p>
<span className="chip-small bg-yellow-100 text-yellow-700 font-light text-body5 py-[3px] px-10"> <MdLocalFireDepartment className='inline-block text-fire transform text-body4 align-middle' /> {project.votes_count} </span>
</div>
</div>)}
</Carousel>
</div>
)
}

View File

@@ -0,0 +1,20 @@
import { useQuery } from "react-query";
import { getLatestProjects } from "../../../api"
import ProjectsRow from "./ProjectsRow";
import { AiFillThunderbolt } from 'react-icons/ai';
export default function ProjectsSection() {
const { data, isLoading } = useQuery("latest-projects", getLatestProjects)
if (isLoading || !data) return null;
return (
<>
<ProjectsRow title={<h3 className="font-bolder text-body3 mb-20">Hottest <AiFillThunderbolt className='inline-block text-yellow-400 transform scale-125' /> apps</h3>
} projects={data[0].projects} />
{data.slice(1).map(({ title, projects }) => <ProjectsRow key={title} title={title} projects={projects} />)}
</>
)
}

View File

@@ -0,0 +1,21 @@
import { motion } from 'framer-motion'
import { ModalCard, modalCardVariants } from '../Shared/Modal/Modal'
export default function LoginCard_1({ onClose, direction, ...props }: ModalCard) {
return (
<motion.div
custom={direction}
variants={modalCardVariants}
initial='initial'
animate="animate"
exit='exit'
className="modal-card max-w-[400px] h-[400px]"
>
<div className="p-24 h-full flex flex-col items-center justify-center">
<h3 className="text-h2 font-bold">Login Modal</h3>
<p className="text-body2 mt-40">WIP</p>
</div>
</motion.div>
)
}

View File

@@ -0,0 +1,78 @@
import { motion } from 'framer-motion'
import { BiArrowBack } from 'react-icons/bi'
import { BsJoystick } from 'react-icons/bs'
import { MdLocalFireDepartment } from 'react-icons/md';
import { ModalCard, modalCardVariants } from '../Shared/Modal/Modal';
import { useQuery } from 'react-query';
import { getProjectById } from '../../api';
import { useAppDispatch } from '../../utils/hooks';
import { Direction, ModalId, openModal, setDirection } from '../../redux/features/modals.slice';
export default function ProjectCard({ onClose, direction, ...props }: ModalCard) {
const { data: project, isLoading } = useQuery(['get-project', props.projectId], () => getProjectById(props.projectId))
const dispatch = useAppDispatch();
if (isLoading || !project) return <></>;
const onClaim = () => {
dispatch(setDirection(Direction.NEXT));
dispatch(openModal({ modalId: ModalId.Login1, initialModalProps: { projectId: props.projectId } }))
}
return (
<motion.div
custom={direction}
variants={modalCardVariants}
initial='initial'
animate="animate"
exit='exit'
className="modal-card"
>
<div className="relative h-[152px]">
<img className="w-full h-full object-cover" src={project.cover_image} alt="" />
<button className="w-[48px] h-[48px] bg-white absolute top-1/2 left-32 -translate-y-1/2 rounded-full hover:bg-gray-200 text-center" onClick={onClose}><BiArrowBack className=' inline-block text-body1' /></button>
</div>
<div className="p-24">
<div className="flex gap-24 items-center">
<div className="flex-shrink-0 w-[93px] h-[93px] rounded-md overflow-hidden">
<img className="w-full h-full object-cover" src={project.thumbnail_image} alt="" />
</div>
<div>
<h3 className="text-h3 font-regular">{project.title}</h3>
<a className="text-blue-400 font-regular text-body4" target='_blank' rel="noreferrer" href={project.website}>{project.website}</a>
</div>
<div className="flex ml-auto gap-16">
<button className="btn btn-primary py-12 px-24 rounded-lg my-16">Play <BsJoystick /></button>
<button className="btn bg-yellow-100 hover:bg-yellow-200 py-12 px-24 rounded-lg my-16">Vote <MdLocalFireDepartment className='text-fire' /></button>
</div>
</div>
<p className="mt-40 text-body4 leading-normal">{project.description}</p>
<div className="flex gap-24 mt-24 flex-wrap">
<span className="chip-small bg-red-100 text-red-800 font-regular"> payments </span>
<span className="chip-small bg-primary-100 text-primary-800 font-regular"> lightining </span>
</div>
<div className="mt-40">
<h3 className="text-h5 font-bold">Screen Shots</h3>
<div className="grid grid-cols-1 justify-items-center md:grid-cols-2 gap-x-24 gap-y-20">
<div className="w-full max-w-[260px] self-center h-[130px] bg-gray-300 rounded-xl"></div>
<div className="w-full max-w-[260px] self-center h-[130px] bg-gray-300 rounded-xl"></div>
<div className="w-full max-w-[260px] self-center h-[130px] bg-gray-300 rounded-xl"></div>
<div className="w-full max-w-[260px] self-center h-[130px] bg-gray-300 rounded-xl"></div>
</div>
</div>
<hr className="my-40" />
<div className="text-center">
<h3 className="text-body4 font-regular">Are you the creator of this project?</h3>
<button className="btn py-12 px-24 rounded-lg my-16" onClick={onClaim}>Claim 🖐</button>
</div>
</div>
</motion.div>
)
}

View File

@@ -0,0 +1,75 @@
import { AnimatePresence, motion } from "framer-motion";
import { ReactElement, useEffect, useRef } from "react";
import { Direction } from "../../../redux/features/modals.slice";
import { Portal } from "../Portal/Portal";
export interface ModalCard {
onClose?: () => void;
direction: number;
modalCard: ReactElement
}
export const modalCardVariants = {
initial: (direction: any) => {
if (direction === Direction.START) return { opacity: 0, y: 300 };
else if (direction === Direction.NEXT) return { opacity: 0, x: 300 };
else if (direction === Direction.PREVIOUS) return { opacity: 0, x: -300 };
return {}
},
animate: {
x: 0, y: 0, opacity: 1, transition: { type: "spring" }
},
exit: (direction: Direction) => {
const transition = { ease: "easeIn" }
if (direction === Direction.EXIT) return { transition, opacity: 0, y: 300 };
else if (direction === Direction.NEXT) return { transition, opacity: 0, x: -300 };
else if (direction === Direction.PREVIOUS) return { transition, opacity: 0, x: 300 };
return {}
},
}
interface Props {
isOpen?: boolean;
onClose?: () => void,
maxWidth?: string;
children: ReactElement
}
export default function Modal({ children, isOpen = true, onClose = () => { }, maxWidth = "max-w-[600px]" }: Props) {
const ref = useRef<HTMLDivElement>(null);
const handleOutsideClick = (e: any) => {
if (e.target === ref.current) onClose();
}
useEffect(() => {
if (isOpen) document.body.style.overflowY = "hidden";
else document.body.style.overflowY = "initial";
}, [isOpen])
return (
<Portal>
<AnimatePresence exitBeforeEnter>
{isOpen && <motion.div
ref={ref}
onClick={handleOutsideClick}
className={`fixed overscroll-y-none inset-0 bg-gray-300 bg-opacity-70 overflow-y-auto h-full w-full`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{
opacity: 0,
transition: { ease: "easeInOut" },
}}
>
<div
className={`w-full ${maxWidth} mx-auto py-64`}
>
{children}
</div>
</motion.div>}
</AnimatePresence>
</Portal>
)
}

View File

@@ -0,0 +1,100 @@
import { AnimatePresence, motion } from "framer-motion";
import { useEffect, useRef } from "react";
import { closeModal, Direction, ModalId } from "../../../redux/features/modals.slice";
import { useAppDispatch, useAppSelector } from "../../../utils/hooks";
import LoginCard_1 from "../../Login/LoginCard-1";
import ProjectCard from "../../Project/ProjectCard";
import { Portal } from "../Portal/Portal";
export interface ModalCard {
onClose?: () => void;
direction: number;
[key: string]: any;
}
export const modalCardVariants = {
initial: (direction: any) => {
if (direction === Direction.START) return { opacity: 0, y: 300 };
else if (direction === Direction.NEXT) return { opacity: 0, x: 300 };
else if (direction === Direction.PREVIOUS) return { opacity: 0, x: -300 };
return {}
},
animate: {
x: 0, y: 0, opacity: 1, transition: { type: "spring" }
},
exit: (direction: Direction) => {
const transition = { ease: "easeIn" }
if (direction === Direction.EXIT) return { transition, opacity: 0, y: 300 };
else if (direction === Direction.NEXT) return { transition, opacity: 0, x: -300 };
else if (direction === Direction.PREVIOUS) return { transition, opacity: 0, x: 300 };
return {}
},
}
const ModalsMap = (modalId: ModalId) => {
switch (modalId) {
case ModalId.Project:
return ProjectCard;
case ModalId.Login1:
return LoginCard_1;
default:
return () => <></>
}
}
export default function Modal() {
const { isOpen, modalId, direction, initialModalProps } = useAppSelector(state => ({ isOpen: state.modals.isOpen, modalId: state.modals.openModalId, direction: state.modals.direction, initialModalProps: state.modals.initialModalProps }))
const ref = useRef<HTMLDivElement>(null);
const dispatch = useAppDispatch();
const onClose = () => dispatch(closeModal());
const handleOutsideClick = (e: any) => {
console.log(e.target);
if (e.target === ref.current) onClose();
}
useEffect(() => {
if (isOpen) document.body.style.overflowY = "hidden";
else document.body.style.overflowY = "initial";
}, [isOpen]);
const Child = ModalsMap(modalId);
return (
<Portal>
<AnimatePresence exitBeforeEnter>
{isOpen && <motion.div
onClick={handleOutsideClick}
className={`fixed overscroll-y-none overflow-x-hidden inset-0 bg-gray-300 bg-opacity-70 overflow-y-auto h-full w-full`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{
opacity: 0,
transition: { ease: "easeInOut" },
}}
>
<div
ref={ref}
className={`w-screen min-h-screen flex justify-center items-center py-64`}
>
<AnimatePresence exitBeforeEnter>
<Child onClose={onClose} direction={direction} {...initialModalProps} />
</AnimatePresence>
</div>
</motion.div>}
</AnimatePresence>
</Portal>
)
}

View File

@@ -0,0 +1,83 @@
import { motion } from "framer-motion";
import { useState } from "react";
import { FiMenu } from 'react-icons/fi';
import { GrClose } from 'react-icons/gr';
import { BsSearch } from 'react-icons/bs'
import { navLinks } from "./Navbar";
import { AiFillThunderbolt } from 'react-icons/ai';
const navBtnVariant = {
menuHide: { rotate: 90, opacity: 0 },
menuShow: { rotate: 0, opacity: 1 },
closeHide: { rotate: -90, opacity: 0 },
closeShow: { rotate: 0, opacity: 1 },
}
const navListVariants = {
init: { x: 0 },
show: { x: "-100%" },
hide: { x: 0 }
}
export default function NavMobile() {
const [open, setOpen] = useState(false)
const handleClick = () => {
if (open)
document.body.classList.remove('overflow-y-hidden')
else
document.body.classList.add('overflow-y-hidden')
setOpen(open => !open);
}
return (
<nav className='block lg:hidden overflow-hidden z-[2010]'>
<div className="p-16 w-screen flex items-center">
<div className="w-40 h-40 bg-gray-100 rounded-8 mr-16 overflow-hidden">
<img className="w-full h-full object-cover" src="https://www.figma.com/file/OFowr5RJk9YZCW35KT7D5K/image/07b85d84145942255afd215b3da26dbbf1dd03bd?fuid=772401335362859303" alt="" />
</div>
<h2 className="text-h5 font-bold mr-64">makers.bolt.fun</h2>
<button className='rounded-full ml-auto mr-16 text-2xl w-[50px] h-[50px] hover:bg-gray-200' onClick={handleClick}>
{!open ? (<motion.div key={open ? 1 : 0} variants={navBtnVariant} initial='menuHide' animate='menuShow'><FiMenu /></motion.div>)
: (<motion.div key={open ? 1 : 0} variants={navBtnVariant} initial='closeHide' animate='closeShow'><GrClose /></motion.div>)}
</button>
</div>
<div className="fixed overflow-hidden left-0 pointer-events-none z-[2010] w-full min-h-[calc(100vh-76px)]">
{open && <div onClick={handleClick} className='pointer-events-auto absolute left-0 w-full min-h-full bg-gray-400 opacity-20'>
</div>}
<motion.div
className="pointer-events-auto bg-white w-full sm:max-w-[400px] min-h-full absolute left-full border shadow-2xl sm:p-32 flex flex-col"
variants={navListVariants}
animate={open ? "show" : "hide"}
>
<div className="px-16">
<div className='relative'>
<BsSearch className='absolute top-1/2 left-20 transform -translate-x-1/2 -translatey-1/2 text-gray-500' />
<input className="btn bg-gray-100 w-full py-12 px-40 rounded-24 mt-16 placeholder-gray-500" placeholder="Search" />
</div>
<button className="btn btn-primary w-full py-12 px-40 rounded-24 my-16">Submit <AiFillThunderbolt className='inline-block text-yellow-400 transform scale-125' /> app</button>
</div>
<ul className="py-16 gap-64 border-t">
{navLinks.map((link, idx) => <li key={idx} className="text-body3 p-16 hover:bg-gray-200">
<a href={link.url}><link.icon className={`text-body2 inline-block mr-12 ${link.color}`} /> {link.text} </a></li>
)}
</ul>
<ul className="px-16 py-16 pb-32 flex flex-wrap gap-y-12 border-t mt-auto">
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">About Us</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Support</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Press</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Contacts</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Careers</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Sitemap</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Legal</a></li>
<li className="text-body4 text-gray-500 hover:text-gray-700 w-1/2"><a href="/">Cookies Settings</a></li>
</ul>
</motion.div>
</div>
</nav>
)
}

View File

@@ -0,0 +1,36 @@
import NavMobile from "./NavMobile";
import { FaHome } from 'react-icons/fa';
import { MdLocalFireDepartment } from 'react-icons/md';
import { IoExtensionPuzzle } from 'react-icons/io5';
import { AiFillThunderbolt } from 'react-icons/ai';
export const navLinks = [
{ text: "Explore", url: "/", icon: FaHome, color: 'text-primary-600' },
{ text: "Hottest", url: "/", icon: MdLocalFireDepartment, color: 'text-primary-600' },
{ text: "Categories", url: "/", icon: IoExtensionPuzzle, color: 'text-primary-600' },
]
export default function Navbar() {
return (
<>
<NavMobile />
{/* Desktop Nav */}
<nav className="hidden lg:flex py-36 px-32 items-center">
<h2 className="text-h5 font-bold mr-40 lg:mr-64">makers.bolt.fun</h2>
<ul className="flex gap-32 lg:gap-64">
{navLinks.map((link, idx) => <li key={idx} className="text-body4 hover:text-primary-600">
<a href={link.url}><link.icon className={`text-body2 align-middle inline-block mr-8 ${link.color}`} /> {link.text}</a></li>
)}
</ul>
<div className="ml-auto">
<button className="btn btn-primary py-12 px-32 lg:px-40">Submit <AiFillThunderbolt className='inline-block text-yellow-400 transform scale-125' /> app</button>
<span className="chip mx-12 h-full mr-24 p-12"><AiFillThunderbolt className='inline-block text-yellow-400 transform scale-125' /> 2.2k sats </span>
</div>
</nav>
</>
)
}

View File

@@ -0,0 +1,17 @@
import React from "react";
import ReactDOM from "react-dom";
export const Portal = ({ children, className = "root-portal", el = "div" }) => {
const [container] = React.useState(document.createElement(el));
container.classList.add(className);
React.useEffect(() => {
document.body.appendChild(container);
return () => {
document.body.removeChild(container);
};
}, [container]);
return ReactDOM.createPortal(children, container);
};