modals open with selected project

This commit is contained in:
Paul Miller
2022-04-03 12:43:12 -04:00
parent 9726000b73
commit 20577256d5
12 changed files with 108 additions and 33 deletions

View File

@@ -7,7 +7,7 @@ export type CreditItemProps = {
}
const CreditItem: React.FC<CreditItemProps> = ({ image, nym, link }) => {
return (
<a href={link} target="_blank">
<a href={link} target="_blank" rel="noreferrer">
<div className="p-4 flex flex-col items-center gap-2">
<Image width={192} height={192} src={image} alt={nym} className="border border-white rounded" />
<h3 className="text-white font-mono text-xl">{nym}</h3>

View File

@@ -69,15 +69,15 @@ const Credits = () => {
<section className="bg-black p-4 flex flex-col items-center">
<h1 className="text-white my-4">Board</h1>
<div className="container flex flex-wrap items-center justify-center mb-8">
{board.map(b =>
<CreditItem image={b.image} link={b.link} nym={b.nym} />
{board.map((b, i) =>
<CreditItem key={i} image={b.image} link={b.link} nym={b.nym} />
)}
</div>
<h1 className="text-white my-4">Supporters</h1>
<div className="container flex flex-wrap items-center justify-center">
{supporters.map(b =>
<CreditItem image={b.image} link={b.link} nym={b.nym} />
{supporters.map((s, i) =>
<CreditItem key={i} image={s.image} link={s.link} nym={s.nym} />
)}
</div>
</section >

View File

@@ -4,12 +4,19 @@ import waffledog from "../public/waffledog.jpg";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faClose } from "@fortawesome/free-solid-svg-icons";
import DonationForm from "./DonationForm";
import { ProjectItem } from "../utils/types";
type ModalProps = {
isOpen: boolean;
onRequestClose: () => void;
project: ProjectItem | undefined
};
const PaymentModal: React.FC<ModalProps> = ({ isOpen, onRequestClose }) => {
const PaymentModal: React.FC<ModalProps> = ({ isOpen, onRequestClose, project }) => {
if (!project) {
// We never see this yeah?
return (< div />);
}
return (
<ReactModal
isOpen={isOpen}
@@ -32,14 +39,15 @@ const PaymentModal: React.FC<ModalProps> = ({ isOpen, onRequestClose }) => {
<div className="flex flex-col space-y-4 py-4">
<div className="flex gap-4 items-center">
<Image
alt="waffledog"
src={waffledog}
alt={project.title}
src={project.coverImage}
width={96}
height={96}
objectFit="cover"
className="rounded-xl"
/>
<div className="flex flex-col">
<h2 className="font-sans font-bold">Double-spend problem</h2>
<h2 className="font-sans font-bold">{project.title}</h2>
<h3 className="font-sans text-textgray">Plege your support</h3>
</div>
</div>

View File

@@ -6,12 +6,18 @@ import { faTwitter } from "@fortawesome/free-brands-svg-icons";
import Link from "next/link";
import { faArrowRight } from "@fortawesome/free-solid-svg-icons";
import { ProjectItem } from "../utils/types";
import PaymentModal from "./PaymentModal";
const ProjectCard: React.FC<{ project: ProjectItem }> = ({ project }) => {
console.log("project:", project)
export type ProjectCardProps = {
project: ProjectItem;
openPaymentModal: (project: ProjectItem) => void;
}
const ProjectCard: React.FC<ProjectCardProps> = ({ project, openPaymentModal }) => {
const { slug, title, summary, coverImage, git, twitter } = project;
return (
<figure className=" bg-white space-y-4 border border-lightgray rounded-xl">
<figure className=" bg-white space-y-4 border border-lightgray rounded-xl h-full">
<div className="relative h-64">
<Image
alt={title}
@@ -30,7 +36,7 @@ const ProjectCard: React.FC<{ project: ProjectItem }> = ({ project }) => {
<a>@{git}</a>
</Link>
</p>
<p className="prose">
<p className="prose line-clamp-3">
{summary}
</p>
<div className="flex justify-end"></div>
@@ -51,7 +57,7 @@ const ProjectCard: React.FC<{ project: ProjectItem }> = ({ project }) => {
}
</div>
<div className="flex space-x-4 items-center justify-center pt-4">
<button className="bg-black basis-1/2">Donate</button>
<button className="bg-black basis-1/2" onClick={() => openPaymentModal(project)}>Donate</button>
<div className="flex items-center justify-center basis-1/2">
<Link href={`/projects/${slug}`} passHref>
<a>View Details</a>

View File

@@ -3,12 +3,20 @@ import { faArrowRight, faC, faClose } from "@fortawesome/free-solid-svg-icons";
import ProjectCard from "./ProjectCard";
import Link from "next/link";
import { ProjectItem } from "../utils/types";
import { useEffect, useState } from "react";
type ProjectListProps = {
header?: string;
projects: ProjectItem[];
openPaymentModal: (project: ProjectItem) => void;
}
const ProjectList: React.FC<ProjectListProps> = ({ header = "Explore Projects", projects }) => {
const ProjectList: React.FC<ProjectListProps> = ({ header = "Explore Projects", projects, openPaymentModal }) => {
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>();
useEffect(() => {
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
}, [projects])
return (
<section className="p-4 md:p-8 bg-light flex flex-col items-center">
@@ -23,9 +31,9 @@ const ProjectList: React.FC<ProjectListProps> = ({ header = "Explore Projects",
</div>
</div>
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
{projects.slice(0, 3).map((p, i) => (
{sortedProjects && sortedProjects.slice(0, 3).map((p, i) => (
<li key={i} className="">
<ProjectCard project={p} />
<ProjectCard project={p} openPaymentModal={openPaymentModal} />
</li>
))}
</ul>

View File

@@ -1,7 +1,7 @@
.markdown {
@apply leading-relaxed max-w-[60ch] px-4 lg:px-8;
@apply leading-relaxed max-w-[60ch] px-4 lg:px-8 prose;
}
/*
.markdown p,
.markdown ul,
.markdown ol,
@@ -31,4 +31,4 @@
.markdown blockquote {
@apply bg-light py-2 px-4 rounded;
}
} */

17
package-lock.json generated
View File

@@ -29,6 +29,7 @@
"wicg-inert": "^3.1.1"
},
"devDependencies": {
"@tailwindcss/line-clamp": "^0.3.1",
"@tailwindcss/typography": "^0.5.2",
"@types/node": "17.0.21",
"@types/react": "17.0.40",
@@ -513,6 +514,15 @@
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.25.0.tgz",
"integrity": "sha512-cywIoKu3sJnBPQ1eKi3BzFHWslA2ePqHvQhcxp7iYYlo1tWcVgEKTSh7y7hb6GoR4TyT3DwlK4v1vOZpVg8u4Q=="
},
"node_modules/@tailwindcss/line-clamp": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.3.1.tgz",
"integrity": "sha512-pNr0T8LAc3TUx/gxCfQZRe9NB2dPEo/cedPHzUGIPxqDMhgjwNm6jYxww4W5l0zAsAddxr+XfZcqttGiFDgrGg==",
"dev": true,
"peerDependencies": {
"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
}
},
"node_modules/@tailwindcss/typography": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
@@ -5331,6 +5341,13 @@
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.25.0.tgz",
"integrity": "sha512-cywIoKu3sJnBPQ1eKi3BzFHWslA2ePqHvQhcxp7iYYlo1tWcVgEKTSh7y7hb6GoR4TyT3DwlK4v1vOZpVg8u4Q=="
},
"@tailwindcss/line-clamp": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.3.1.tgz",
"integrity": "sha512-pNr0T8LAc3TUx/gxCfQZRe9NB2dPEo/cedPHzUGIPxqDMhgjwNm6jYxww4W5l0zAsAddxr+XfZcqttGiFDgrGg==",
"dev": true,
"requires": {}
},
"@tailwindcss/typography": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",

View File

@@ -30,6 +30,7 @@
"wicg-inert": "^3.1.1"
},
"devDependencies": {
"@tailwindcss/line-clamp": "^0.3.1",
"@tailwindcss/typography": "^0.5.2",
"@types/node": "17.0.21",
"@types/react": "17.0.40",

View File

@@ -9,14 +9,23 @@ import unicorn from "/public/heroes/unicorn.png"
import { getAllPosts, getPostBySlug } from "../utils/md";
import markdownToHtml from "../utils/markdownToHtml";
import Credits from "../components/Credits";
import { ProjectItem } from "../utils/types";
const Home: NextPage<{ projects: any }> = ({ projects }) => {
const [modalOpen, setModalOpen] = useState(false);
const [selectedProject, setSelectedProject] = useState<ProjectItem>();
function closeModal() {
setModalOpen(false);
}
function openPaymentModal(project: ProjectItem) {
console.log("opening index modal...")
setSelectedProject(project);
setModalOpen(true)
}
return (
<>
<Head>
@@ -42,10 +51,10 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
<Image width={388} height={388} src={unicorn} alt="Unicorn" />
</div>
</section>
<ProjectList projects={projects} />
<ProjectList projects={projects} openPaymentModal={openPaymentModal} />
<Credits />
</main>
<PaymentModal isOpen={modalOpen} onRequestClose={closeModal} />
<PaymentModal isOpen={modalOpen} onRequestClose={closeModal} project={selectedProject} />
</>
);
};

View File

@@ -8,6 +8,8 @@ import ProjectList from '../../components/ProjectList'
import BackToProjects from '../../components/BackToProjects'
import { ProjectItem } from '../../utils/types'
import { NextPage } from 'next/types'
import { useState } from 'react'
import PaymentModal from '../../components/PaymentModal'
type SingleProjectPageProps = {
project: ProjectItem;
@@ -17,6 +19,20 @@ type SingleProjectPageProps = {
const Project: NextPage<SingleProjectPageProps> = ({ project, projects }) => {
const router = useRouter()
const [modalOpen, setModalOpen] = useState(false);
const [selectedProject, setSelectedProject] = useState<ProjectItem>();
function closeModal() {
setModalOpen(false);
}
function openPaymentModal() {
console.log("opening single project modal...")
setSelectedProject(project);
setModalOpen(true)
}
const { slug, title, summary, coverImage, git, twitter, content } = project;
if (!router.isFallback && !slug) {
@@ -47,7 +63,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects }) => {
<h5>Raised</h5>
<h4>??? BTC</h4>
</div>
<button>Donate</button>
<button onClick={openPaymentModal}>Donate</button>
</aside>
@@ -65,7 +81,8 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, projects }) => {
</div>
</article>
</div >
<ProjectList projects={projects} header="You might also like..." />
<ProjectList projects={projects} header="You might also like..." openPaymentModal={openPaymentModal} />
<PaymentModal isOpen={modalOpen} onRequestClose={closeModal} project={selectedProject} />
</>
)
}

View File

@@ -1,22 +1,30 @@
import type { NextPage } from "next";
import Head from "next/head";
import { useState } from "react";
import ProjectList from "../../components/ProjectList";
import { useEffect, useState } from "react";
import PaymentModal from "../../components/PaymentModal";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowRight, faC, faClose } from "@fortawesome/free-solid-svg-icons";
import ProjectCard from "../../components/ProjectCard";
import { ProjectItem } from "../../utils/types";
import { getAllPosts } from "../../utils/md";
import markdownToHtml from "../../utils/markdownToHtml";
const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
const [modalOpen, setModalOpen] = useState(false);
const [selectedProject, setSelectedProject] = useState<ProjectItem>();
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>();
useEffect(() => {
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
}, [projects])
function closeModal() {
setModalOpen(false);
}
function openPaymentModal(project: ProjectItem) {
setSelectedProject(project);
setModalOpen(true)
}
// const projects = ["one", "two", "three", "one", "two", "three", "one", "two", "three"];
return (
@@ -29,14 +37,14 @@ const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
<h1>Projects</h1>
</div>
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
{projects.map((p, i) => (
{sortedProjects && sortedProjects.map((p, i) => (
<li key={i} className="">
<ProjectCard project={p} />
<ProjectCard project={p} openPaymentModal={openPaymentModal} />
</li>
))}
</ul>
</section>
<PaymentModal isOpen={modalOpen} onRequestClose={closeModal} />
<PaymentModal isOpen={modalOpen} onRequestClose={closeModal} project={selectedProject} />
</>
);
};

View File

@@ -27,6 +27,7 @@ module.exports = {
},
},
plugins: [
require('@tailwindcss/typography')
require('@tailwindcss/typography'),
require('@tailwindcss/line-clamp'),
],
};