mirror of
https://github.com/MAGICGrants/campaign-site.git
synced 2026-01-09 12:27:59 -05:00
modals open with selected project
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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 >
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
17
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/typography')
|
||||
require('@tailwindcss/typography'),
|
||||
require('@tailwindcss/line-clamp'),
|
||||
],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user