Skip to content

Commit ba999d7

Browse files
Add a new page for fundable projects.
1 parent 4b4d0d8 commit ba999d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+11673
-2
lines changed

docusaurus.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ const config: Config = {
110110
className: "custom_navbar_item",
111111
label: "Blog",
112112
position: "left",
113+
},
114+
{
115+
to: "/fundable/",
116+
className: "custom_navbar_item",
117+
label: "Fundable projects",
118+
position: "right",
119+
className:"fundable_projects"
113120
},
114121
{
115122
to: "/contact/",

src/components/footer/Footer.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ export default function Footer() {
6565
</li>
6666
</ul>
6767
</div>
68+
<div className="col flex-horizontally-centered">
69+
<ul>
70+
<li>
71+
<Link href={"/fundable"}>Fundable projects</Link>
72+
</li>
73+
<li>
74+
<Link href={"/contact"}>Contact us</Link>
75+
</li>
76+
</ul>
77+
</div>
6878
</div>
6979
</div>
7080
</div>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import styles from "./styles.module.css";
2+
3+
export default function GetAQuoteForm() {
4+
return (
5+
<>
6+
<form
7+
action="https://formspree.io/f/xjvndwdq"
8+
method="POST"
9+
className={styles.contact_form}
10+
>
11+
<div className="form-group">
12+
<div>
13+
<label className={styles.form_label}>Project name</label>
14+
</div>
15+
<div className={styles.input_container}>
16+
<input
17+
type="text"
18+
className={styles.small_input}
19+
name="Project name"
20+
id="Project name"
21+
/>
22+
</div>
23+
<div>
24+
<label className={styles.form_label}>Your name</label>
25+
</div>
26+
<div className={styles.input_container}>
27+
<input
28+
type="text"
29+
className={styles.small_input}
30+
name="name"
31+
id="name"
32+
/>
33+
</div>
34+
</div>
35+
<div className="form-group">
36+
<div>
37+
<label className={styles.form_label}>Your company</label>
38+
</div>
39+
<div className={styles.input_container}>
40+
<input className={styles.small_input} name="company" id="company" />
41+
</div>
42+
</div>
43+
<div className="form-group">
44+
<div>
45+
<label className={styles.form_label}>Your email</label>
46+
</div>
47+
<div className={styles.input_container}>
48+
<input
49+
type="text"
50+
className={styles.small_input}
51+
name="email"
52+
id="email"
53+
/>
54+
</div>
55+
</div>
56+
<div className="form-group">
57+
<div>
58+
<label className={styles.form_label}>Your phone number</label>
59+
</div>
60+
<div className={styles.input_container}>
61+
<input
62+
type="text"
63+
className={styles.small_input}
64+
name="phone-number"
65+
id="phone-number"
66+
/>
67+
</div>
68+
</div>
69+
<div className="form-group">
70+
<div>
71+
<label className={styles.form_label}>Your message to us</label>
72+
</div>
73+
<div>
74+
<textarea
75+
className={styles.large_input}
76+
placeholder="Please explain your interests in funding this project"
77+
name="message"
78+
id="message"
79+
></textarea>
80+
</div>
81+
</div>
82+
<div>
83+
<div className={"flex-full-centered" + " "+ styles.send_button_container}>
84+
<input type="submit" value="SEND" className={"link-to-button" + " " + styles.send_button} />
85+
</div>
86+
</div>
87+
</form>
88+
</>
89+
);
90+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
import styles from "./styles.module.css";
3+
import GetAQuoteForm from "./GetAQuoteForm"
4+
import { LargeProjectCardContent } from "./LargeProjectCard";
5+
import { useHistory, useLocation } from "@docusaurus/router";
6+
import { fundableProjectsDetails } from "./projectsDetails";
7+
import Layout from "@theme/Layout";
8+
import { Route } from 'react-router-dom';
9+
import { getCategoryFromProjectPageName } from ".";
10+
11+
function getProjectByLocation(location, history) {
12+
console.log('location:', location);
13+
console.log('history:', history);
14+
const pathName = location.pathname;
15+
console.log('pathName:', pathName)
16+
const list = pathName.split('/');
17+
console.log('list:', list);
18+
console.log(list.length)
19+
20+
const pageName = list[list.length - 1]
21+
console.log(pageName);
22+
23+
}
24+
function GetAQuoteComponent() {
25+
return (
26+
<div className="row">
27+
<div className="col col--6">
28+
29+
</div>
30+
<div className="col col--6">
31+
<div><GetAQuoteForm /></div>
32+
</div>
33+
</div>
34+
)
35+
}
36+
export default function GetAQuotePage() {
37+
return (
38+
<div>
39+
<GetAQuoteComponent/>
40+
</div>
41+
)
42+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import styles from "./styles.module.css";
2+
import Link from "@docusaurus/Link";
3+
import GHPicture from "@site/static/img/socialmedias/GH.svg";
4+
import LinkedInPicture from "@site/static/img/socialmedias/LinkedIn.svg";
5+
import BlueskyPicture from "@site/static/img/socialmedias/Bluesky.svg";
6+
import MastodonPicture from "@site/static/img/socialmedias/Mastodon.svg";
7+
8+
export default function IconContainer({ project }) {
9+
const icons = project.icons
10+
return (
11+
12+
13+
<div className={styles.icon_container}>
14+
{icons.map((Icon, index) => (
15+
<div key={index} className={styles.iconWrapper}>
16+
<Icon height={"42px"} width={"42px"}
17+
alt={
18+
"Icon for the fundable project."
19+
} />
20+
</div>
21+
))}
22+
</div>
23+
);
24+
25+
26+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import styles from "./styles.module.css";
2+
import React from "react";
3+
import IconContainer from "./IconContainer";
4+
import LinkToGetAQuote from "./LinkToGetAQuote";
5+
6+
export function LargeProjectCardContent({ project }) {
7+
return (
8+
<div className={"container"}>
9+
<div className={"row-padding-none"}>
10+
<div className="col col--10">
11+
<div className={styles.large_project_card_title}>{project.title}</div>
12+
</div>
13+
<div style={{ padding: "0 16px" }}><IconContainer project={project} /></div>
14+
</div>
15+
<div className="row">
16+
<div className="col col--10 col--offset-1">
17+
<div className={styles.large_project_card_text_container}>
18+
<div className={styles.large_project_card_section_title}>Overview</div>
19+
<div className={styles.large_project_card_description}>
20+
<project.description />
21+
</div>
22+
<div className={styles.large_project_card_section_title}>Option A</div>
23+
<div className={styles.large_project_card_option}>
24+
{project.optionA}
25+
</div>
26+
<div className={styles.large_project_card_section_title}>Option B</div>
27+
<div className={styles.large_project_card_option}>
28+
{project.optionB}
29+
</div>
30+
<div className={styles.large_project_card_section_title}>Custom Option</div>
31+
<div className={styles.large_project_card_option}>
32+
{project.customOption}
33+
</div>
34+
</div>
35+
</div>
36+
</div>
37+
</div>
38+
)
39+
}
40+
export default function LargeProjectCard({ project }) {
41+
return (
42+
<div className={styles.large_project_card}>
43+
<LargeProjectCardContent project={project} />
44+
<div className="row">
45+
<div className="col col--12">
46+
<div className={styles.large_portrait_card_contact_text}>Are you interested in this project? Either entirely or partially, contact us for more information on how to help us fund it.</div>
47+
<div><LinkToGetAQuote label={"GET A QUOTE"} /></div>
48+
</div>
49+
</div>
50+
</div>
51+
52+
);
53+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { useHistory, useLocation } from "@docusaurus/router";
2+
import { useEffect } from "react";
3+
import styles from "./styles.module.css";
4+
import LargeProjectCard from "./LargeProjectCard";
5+
import { getCategoryFromProjectPageName } from ".";
6+
import FundableProjects from ".";
7+
import Layout from "@theme/Layout";
8+
import { Route } from 'react-router-dom';
9+
10+
11+
export default function LargeProjectCardPage() {
12+
const location = useLocation();
13+
const history = useHistory();
14+
15+
useEffect(() => {
16+
if (location.state?.fromFundable) {
17+
window.scrollTo({ top: location.state.scrollY ?? 0, behavior: 'auto' });
18+
}
19+
}, []);
20+
21+
const handleOverlayClick = () => {
22+
const scrollY = location.state?.scrollY;
23+
setTimeout(() => {
24+
if (scrollY !== undefined) {
25+
window.scrollTo({ top: scrollY, behavior: 'auto' });
26+
}
27+
}, 0);
28+
history.replace('/fundable');
29+
};
30+
31+
const handleClose = () => {
32+
const scrollY = location.state?.scrollY;
33+
if (location.state?.fromFundable) {
34+
history.replace('/fundable');
35+
36+
setTimeout(() => {
37+
if (scrollY !== undefined) {
38+
window.scrollTo({ top: scrollY, behavior: 'auto' });
39+
}
40+
}, 0);
41+
} else {
42+
history.goBack();
43+
}
44+
}
45+
return (
46+
<Layout>
47+
<FundableProjects />
48+
<Route
49+
path="/fundable/:pageName"
50+
render={({ match }) => {
51+
const { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/
52+
const projectsByCategory = getCategoryFromProjectPageName(pageName);
53+
const project = projectsByCategory.find((project) => project.pageName === pageName);
54+
if (!project) return null;
55+
56+
return (
57+
<div className={styles.modal_overlay} onClick={handleOverlayClick}>
58+
<div
59+
className={styles.modal_content}
60+
onClick={(e) => e.stopPropagation()}
61+
>
62+
<button
63+
className="close-button"
64+
style={{
65+
position: "absolute",
66+
top: "10px",
67+
right: "10px",
68+
}}
69+
onClick={handleClose}
70+
/>
71+
<LargeProjectCard project={project} />
72+
</div>
73+
</div>
74+
);
75+
}}
76+
/>
77+
</Layout>
78+
)
79+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import styles from "./styles.module.css";
2+
import Link from "@docusaurus/Link";
3+
4+
export default function LinkToGetAQuote({label}) {
5+
return (
6+
<div className="flex-full-centered">
7+
<Link
8+
className={"link-to-button" + " " + styles.link_to_get_a_quote}
9+
href="/fundable/GetAQuote"
10+
>
11+
{label}
12+
</Link>
13+
</div>
14+
);
15+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// src/components/ScrollSidebar.js
2+
import React, { useEffect, useState } from 'react';
3+
import styles from "./styles.module.css";
4+
5+
const sections = [
6+
{ id: 'jupyter-ecosystem', label: 'Jupyter Ecosystem' },
7+
{ id: 'project-management', label: 'Project Management' },
8+
];
9+
10+
export default function MenuSideBar() {
11+
const [activeSectionId, setActiveSectionId] = useState(null);
12+
13+
useEffect(() => {
14+
const handleScroll = () => {
15+
const scrollPosition = window.scrollY + 200;
16+
for (const section of sections) {
17+
const element = document.getElementById(section.id);
18+
if (element && element.offsetTop <= scrollPosition) {
19+
setActiveSectionId(section.id);
20+
}
21+
}
22+
};
23+
window.addEventListener('scroll', handleScroll);
24+
handleScroll();
25+
return () => window.removeEventListener('scroll', handleScroll);
26+
}, []);
27+
28+
return (
29+
<div className={styles.menu_sidebar_container}>
30+
<aside className={styles.menu_sidebar}>
31+
<ul style={{ listStyle: 'none', padding: "0px" }}>
32+
{sections.map((section) => (
33+
<li key={section.id}>
34+
<a
35+
href={`#${section.id}`}
36+
className={`${activeSectionId === section.id ? styles.active_section : ''}`}
37+
>
38+
<span className={styles.indicator} />
39+
<span className={styles.menu_sidebar_item}>{section.label}</span>
40+
</a>
41+
42+
</li>
43+
))}
44+
</ul>
45+
</aside>
46+
</div>
47+
);
48+
}

0 commit comments

Comments
 (0)