@@ -71,42 +71,59 @@ export default function Grants({
7171}) {
7272 const [activeTags, setTags] = useState([]);
7373 const [activeTypes, setTypes] = useState(types);
74+ const [includeOpen, setIncludeOpen] = useState(true);
7475 const [includeCompleted, setIncludeCompleted] = useState(false);
76+ const [includeInProgress, setIncludeInProgress] = useState(false);
7577 const [tab, setTab] = useState(0);
7678 const post = {
7779 title: "Grants",
7880 description: "Contribute to the Urbit project while earning address space.",
7981 };
8082
81− const postsByCompletion = posts.filter((post) => {
82− return includeCompleted
83− ? true
84− : !post.extra.completed && post.extra.assignee === "";
83+ const annotatedPosts = posts.map((post) => {
84+ if (post.extra.completed) {
85+ return { ...post, status: "completed" };
86+ } else if (post.extra.assignee && post.extra.assignee.length > 0) {
87+ return { ...post, status: "wip" };
88+ } else {
89+ return { ...post, status: "open" };
90+ }
8591 });
8692
87− const filteredPosts = postsByCompletion.filter((post) => {
93+ const byStatus = (post) => {
94+ return (
95+ (includeOpen ? post.status === "open" : false) ||
96+ (includeCompleted ? post.status === "completed" : false) ||
97+ (includeInProgress ? post.status === "wip" : false)
98+ );
99+ };
100+
101+ const postsByStatus = annotatedPosts.filter(byStatus);
102+
103+ const filteredPosts = annotatedPosts.filter((post) => {
88104 // Posts are returned if they match both the selected category and selected tags, or if the user has no category filters set.
89105 const hasCategory = post.taxonomies.grant_category.some((category) =>
90106 activeTags.includes(category)
91107 );
108+
92109 const noTagsSelected = activeTags.length === 0;
93110 const hasType = post.taxonomies.grant_type.some((type) =>
94111 activeTypes.includes(type)
95112 );
96113
97− return (hasCategory || noTagsSelected) && hasType;
114+ return (hasCategory || noTagsSelected) && byStatus(post) && hasType;
98115 });
99116
100− const allCount = postsByCompletion.length;
117+ const allCount = postsByStatus.length;
101118
102119 const counts = {
103− Bounty: postsByCompletion.filter((post) =>
120+ Bounty: postsByStatus.filter((post) =>
104121 post.taxonomies.grant_type.includes("Bounty")
105122 ).length,
106− Apprenticeship: postsByCompletion.filter((post) =>
123+ Apprenticeship: postsByStatus.filter((post) =>
107124 post.taxonomies.grant_type.includes("Apprenticeship")
108125 ).length,
109− Proposal: postsByCompletion.filter((post) =>
126+ Proposal: postsByStatus.filter((post) =>
110127 post.taxonomies.grant_type.includes("Proposal")
111128 ).length,
112129 };
@@ -123,7 +140,7 @@ export default function Grants({
123140 // Heading and introduction
124141 }
125142 <Section wide short>
126− <div className="flex flex-column justify-between">
143+ <div className="flex flex-column justify-between pb-16">
127144 <div>
128145 <h1 className="pb-16">Grants</h1>
129146 <p className="mb-8">
@@ -137,7 +154,23 @@ export default function Grants({
137154 at urbit.org, Tlon developers, and community mentors.
138155 </p>
139156 </div>
140− <TableOfContents staticPosition noh3s />
157+ </div>
158+ <div className="flex flex-wrap">
159+ <Link href="#find-a-grant">
160+ <button className="button-lg bg-green text-white mr-2">
161+ View Grants
162+ </button>
163+ </Link>
164+ <Link href="#proposals">
165+ <button className="button-lg bg-blue text-white mr-2">
166+ Submit a Proposal
167+ </button>
168+ </Link>
169+ <Link href="#gifts">
170+ <a className="button-lg bg-ultraDeepWall text-white mr-2">
171+ Recent Gifts
172+ </a>
173+ </Link>
141174 </div>
142175 </Section>
143176 {
@@ -171,12 +204,79 @@ export default function Grants({
171204 })}
172205 </div>
173206 </Section>
174− {
175− // Find a Grant
176− }
207+ {/* Submit a proposal */}
208+ <Section wide>
209+ <h2 className="mb-16" id="proposals">
210+ Proposals
211+ </h2>
212+ <p className="mb-8">
213+ Contributors are also welcome to have their personal projects
214+ considered as a proposal. If you'd like to propose a project for the
215+ grants program, first review our
216+ <a href="/grant-submission-guide">submission guide</a>, and feel
217+ free to{" "}
218+ <a href="https://airtable.com/shrCi54rEDxgSZr3z">
219+ submit your proposal
220+ </a>
221+ .
222+ </p>
223+
224+ <Link href="#find-a-grant">
225+ <button
226+ className="button-lg bg-blue text-white mr-2"
227+ onClick={() => {
228+ setIncludeInProgress(true);
229+ setIncludeCompleted(true);
230+ setTab(1);
231+ setTypes(["Proposal"]);
232+ }}
233+ >
234+ View Proposals
235+ </button>
236+ </Link>
237+ </Section>
238+ {/* Gift Grants */}
239+ <Section wide>
240+ <div className="pb-16">
241+ <h2 className="pb-16" id="gifts">
242+ Gifts
243+ </h2>
244+ <p className="mb-8">
245+ Gifts are given post-facto for exceptional contributions.
246+ </p>
247+ {/* Uncomment once people added to content/gifts folder. */}
248+ {/* {gifts.map((e) => {
249+ return (
250+ <div className="bg-wall rounded-xl p-4 my-8 flex justify-between">
251+ <p className="font-semibold">
252+ {e.name}
253+ </p>
254+ <p>{e.planet}</p>
255+ <p>{e.date}</p>
256+ <a className="type-p" href={e.link}>Link</a>
257+ </div>
258+ )
259+ })} */}
260+ <div className="flex flex-wrap">
261+ <PostPreview
262+ post={giftPosts[0]}
263+ className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
264+ key={giftPosts[0].slug}
265+ section={giftPosts[0].section}
266+ />
267+ <PostPreview
268+ post={giftPosts[1]}
269+ className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
270+ key={giftPosts[1].slug}
271+ section={giftPosts[1].section}
272+ />
273+ </div>
274+ </div>
275+ </Section>
276+ {/* Find a Grant */}
177277 <Section wide>
178278 <h2 id="find-a-grant" className="pb-8">
179− Find A Grant
279+ Find a Grant
180280 </h2>
181281 <h5 className="text-black font-semibold my-2">Work Programs</h5>
182282 <div className="flex flex-wrap items-center pb-2">
@@ -233,6 +333,13 @@ export default function Grants({
233333 </div>
234334 {
235335 <div className="pb-8 flex items-center">
336+ <button
337+ className="mr-4 badge-sm bg-black text-white"
338+ onClick={() => setIncludeOpen(!includeOpen)}
339+ >
340+ {includeOpen ? "Exclude Open" : "Include Open"}
341+ </button>
342+
236343 <button
237344 className="mr-4 badge-sm bg-black text-white"
238345 onClick={() => setIncludeCompleted(!includeCompleted)}
@@ -240,6 +347,15 @@ export default function Grants({
240347 {includeCompleted ? "Exclude Completed" : "Include Completed"}
241348 </button>
242349
350+ <button
351+ className="mr-4 badge-sm bg-black text-white"
352+ onClick={() => setIncludeInProgress(!includeInProgress)}
353+ >
354+ {includeInProgress
355+ ? "Exclude In Progress"
356+ : "Include In Progress"}
357+ </button>
358+
243359 <h4>
244360 Showing {filteredPosts.length} grant
245361 {filteredPosts.length === 1 ? "" : "s"}
@@ -250,63 +366,6 @@ export default function Grants({
250366 return <GrantPreview grant={post} />;
251367 })}
252368 </Section>
253− {/* Submit a proposal */}
254− <Section wide>
255− <h2 className="mb-16" id="proposals">
256− Proposals
257− </h2>
258− <p className="mb-8">
259− Contributors are also welcome to have their personal projects
260− considered as a proposal. If you'd like to propose a project for the
261− grants program, first review our
262− <a href="/grant-submission-guide">submission guide</a>, and feel
263− free to{" "}
264− <a href="https://airtable.com/shrCi54rEDxgSZr3z">
265− submit your proposal
266− </a>
267− .
268− </p>
269− </Section>
270− {
271− // Gift Grants
272− }
273− <Section wide>
274− <div className="pb-16">
275− <h2 className="pb-16" id="gifts">
276− Gifts
277− </h2>
278− <p className="mb-8">
279− Gifts are given post-facto for exceptional contributions.
280− </p>
281− {/* Uncomment once people added to content/gifts folder. */}
282− {/* {gifts.map((e) => {
283− return (
284− <div className="bg-wall rounded-xl p-4 my-8 flex justify-between">
285− <p className="font-semibold">
286− {e.name}
287− </p>
288− <p>{e.planet}</p>
289− <p>{e.date}</p>
290− <a className="type-p" href={e.link}>Link</a>
291− </div>
292− )
293− })} */}
294− <div className="flex flex-wrap">
295− <PostPreview
296− post={giftPosts[0]}
297− className={`w-full md:w-1/2 pr-0 pb-8 md:pr-4`}
298− key={giftPosts[0].slug}
299− section={giftPosts[0].section}
300− />
301− <PostPreview
302− post={giftPosts[1]}
303− className={`w-full md:w-1/2 pl-0 pb-8 md:pl-4`}
304− key={giftPosts[1].slug}
305− section={giftPosts[1].section}
306− />
307− </div>
308− </div>
309− </Section>
310369 </SingleColumn>
311370 <Footer />
312371 </Container>