Skip to content

Commit

Permalink
Added a shrinkable create button and a modal to create posts
Browse files Browse the repository at this point in the history
  • Loading branch information
luloxi committed Sep 28, 2024
1 parent cf5af62 commit f4e8b34
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 44 deletions.
13 changes: 8 additions & 5 deletions packages/nextjs/app/create/Create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { ImageUploader } from "./_components/ImageUploader";
import { MetadataForm } from "./_components/MetadataForm";
import { MintingButtons } from "./_components/MintingButtons";
import generateTokenURI from "./_components/generateTokenURI";
import type { NextPage } from "next";

export const Create: NextPage = () => {
// import type { NextPage } from "next";

const Create = () => {
const [description, setDescription] = useState("");
const [yourJSON, setYourJSON] = useState<object>({});
const [uploadedImageIpfsPath, setUploadedImageIpfsPath] = useState(""); // NEW: For image IPFS path
Expand Down Expand Up @@ -39,13 +40,13 @@ export const Create: NextPage = () => {

{/* Metadata and Attributes Forms */}
<div className="flex flex-col gap-3 md:flex-row items-center justify-center space-x-4 mb-4">
<div className="text-left w-full">
<MetadataForm description={description} setDescription={setDescription} />
</div>
<ImageUploader
image={uploadedImageIpfsPath}
setUploadedImageIpfsPath={setUploadedImageIpfsPath} // NEW: Set the uploaded image IPFS path here
/>
<div className="text-left w-full">
<MetadataForm description={description} setDescription={setDescription} />
</div>
</div>

{/* JSON Viewer */}
Expand All @@ -63,3 +64,5 @@ export const Create: NextPage = () => {
</>
);
};

export default Create;
45 changes: 45 additions & 0 deletions packages/nextjs/app/create/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useEffect, useRef } from "react";
import { XMarkIcon } from "@heroicons/react/24/outline";

interface ModalProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
}

const Modal: React.FC<ModalProps> = ({ isOpen, onClose, children }) => {
const modalRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (modalRef.current && !modalRef.current.contains(event.target as Node)) {
onClose();
}
};

document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [onClose]);

return (
<div
className={`fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 ${
isOpen ? "animate-show" : "animate-hide"
}`}
>
<div ref={modalRef} className="relative w-full max-w-2xl mx-4 md:mx-0">
<button
className="absolute p-2 top-2 right-2 md:top-6 md:right-6 bg-red-600 text-white hover:text-red-800 rounded-full"
onClick={onClose}
>
<XMarkIcon className="h-6 w-6" />
</button>
{children}
</div>
</div>
);
};

export default Modal;
7 changes: 1 addition & 6 deletions packages/nextjs/app/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Create } from "./Create";
import type { NextPage } from "next";
import { getMetadata } from "~~/utils/scaffold-eth/getMetadata";

Expand All @@ -8,11 +7,7 @@ export const metadata = getMetadata({
});

const CreatePage: NextPage = () => {
return (
<>
<Create />
</>
);
return <></>;
};

export default CreatePage;
75 changes: 58 additions & 17 deletions packages/nextjs/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,63 @@
import React from "react";
import React, { useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { faBell, faHome, faPlus, faSearch } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Create from "../app/create/Create";
import Modal from "../app/create/Modal";
import { HeartIcon } from "@heroicons/react/24/outline";
import { BellIcon, EnvelopeIcon, HomeIcon, MagnifyingGlassIcon, PlusIcon } from "@heroicons/react/24/solid";

// Import Modal

/**
* Site footer
*/
export const Footer = () => {
const pathname = usePathname();
const [showPlusIcon, setShowPlusIcon] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);

useEffect(() => {
let lastScrollY = window.scrollY;

const handleScroll = () => {
if (window.scrollY > lastScrollY) {
// Scrolling down
setShowPlusIcon(false);
} else {
// Scrolling up
setShowPlusIcon(true);
}
lastScrollY = window.scrollY;
};

window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);

const openModal = () => {
setIsModalOpen(true);
};

const closeModal = () => {
setIsModalOpen(false);
};

return (
<>
<div
className={`fixed bottom-16 lg:bottom-8 right-8 p-3 bg-blue-600 cursor-pointer hover:bg-blue-800 text-white rounded-full shadow-lg ${
showPlusIcon ? "animate-show" : "animate-hide"
}`}
onClick={openModal}
>
<PlusIcon className="h-10 w-10" />
</div>

<Modal isOpen={isModalOpen} onClose={closeModal}>
<Create />
</Modal>
<div className="min-h-0 py-5 px-1 lg:mb-0">
<div className="w-full">
<ul className="menu menu-horizontal w-full">
Expand Down Expand Up @@ -42,30 +87,26 @@ export const Footer = () => {
</div>
<footer className="sticky lg:hidden bottom-0 w-full bg-base-100 px-4 py-2 flex justify-around items-center">
<Link href="/" passHref>
<FontAwesomeIcon
icon={faHome}
className={`h-6 w-6 ${pathname === "/" ? "text-blue-600" : "hover:text-blue-600"}`}
/>
<HomeIcon className={`h-6 w-6 ${pathname === "/" ? "text-blue-600" : "hover:text-blue-600"}`} />
</Link>

<Link href="/create" passHref>
<FontAwesomeIcon
icon={faPlus}
className={`h-6 w-6 ${pathname === "/create" ? "text-blue-600" : "hover:text-blue-600"}`}
<Link href="/not-found" passHref>
<MagnifyingGlassIcon
className={`h-6 w-6 text-red-600 ${pathname === "/search" ? "text-blue-600" : "hover:text-blue-600"}`}
/>
</Link>

<Link href="/not-found" passHref>
<FontAwesomeIcon
icon={faSearch}
className={`h-6 w-6 text-red-500 ${pathname === "/profile" ? "text-blue-600" : "hover:text-blue-600"}`}
<BellIcon
className={`h-6 w-6 text-red-600 ${
pathname === "/notifications" ? "text-blue-600" : "hover:text-blue-600"
}`}
/>
</Link>

<Link href="/not-found" passHref>
<FontAwesomeIcon
icon={faBell}
className={`h-6 w-6 text-red-500 ${pathname === "/search" ? "text-blue-600" : "hover:text-blue-600"}`}
<EnvelopeIcon
className={`h-6 w-6 text-red-600 ${pathname === "/messages" ? "text-blue-600" : "hover:text-blue-600"}`}
/>
</Link>
</footer>
Expand Down
20 changes: 4 additions & 16 deletions packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import React, { useRef, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { SwitchTheme } from "./SwitchTheme";
import { faHome, faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { hardhat } from "viem/chains";
import { useAccount } from "wagmi";
import { HomeIcon } from "@heroicons/react/24/solid";
import { FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
import { useOutsideClick, useScaffoldReadContract, useTargetNetwork } from "~~/hooks/scaffold-eth";

Expand Down Expand Up @@ -56,28 +55,17 @@ export const Header = () => {
<div className="flex flex-row gap-3">
<Link href="/" passHref>
<button
className={`bg-transparent hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-2xl ${
className={`bg-transparent hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-xl ${
pathname === "/" ? "text-blue-600" : ""
}`}
>
<div className="flex flex-row items-center justify-center gap-2">
<FontAwesomeIcon icon={faHome} className="h-6 w-6" />
<HomeIcon className="h-6 w-6" />

<span>Home</span>
</div>
</button>
</Link>
<Link href="/create" passHref>
<button
className={` bg-transparent hover:bg-base-200 border-none hidden lg:flex flex-row items-center justify-center text-2xl ${
pathname === "/create" ? "text-blue-600" : ""
}`}
>
<div className="flex flex-row items-center justify-center gap-2">
<FontAwesomeIcon icon={faPlus} className="h-6 w-6" />
<span>Create</span>
</div>
</button>
</Link>
</div>
</div>

Expand Down
30 changes: 30 additions & 0 deletions packages/nextjs/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
@import "tailwindcss/utilities";

/* Added by Lulox */
/* CSS Animations */
@keyframes show {
0% {
transform: translateY(100%) scale(0);
opacity: 0;
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
}

@keyframes hide {
0% {
transform: translateY(0) scale(1);
opacity: 1;
}
100% {
transform: translateY(100%) scale(0);
opacity: 0;
}
}

.animate-show {
animation: show 0.5s forwards;
}

.animate-hide {
animation: hide 0.5s forwards;
}

.cool-button {
appearance: button;
Expand Down

0 comments on commit f4e8b34

Please sign in to comment.