Skip to content

Commit 0fad0bc

Browse files
authored
Merge pull request #4252 from cpinitiative/add-january-announcements-and-prettify-banner
Added 2024 announcements and new banner
2 parents 4ab8046 + 36116c3 commit 0fad0bc

11 files changed

+208
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
date: 'Jan 25th, 2024'
3+
id: usaco-january-2024-workshop
4+
title: "USACO January 2024 Contest Workshop"
5+
order: 9
6+
---
7+
8+
Learn how to solve the Bronze/Silver problems by experienced instructors from the USACO Jan 2024 contest, from intuition to code!
9+
Find more information and the registration link for the workshop [here!](https://joincpi.org/workshops/jan24)

announcements/2024 Spring Classes.mdx

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
date: 'Jan 23th, 2024'
3+
id: usaco-spring-2024-classes
4+
title: "USACO Spring 2024 Classes Registration Open!"
5+
order: 7
6+
---
7+
8+
Registration for the Spring Session of USACO classes are now open! Head over to
9+
the [CPI website](https://joincpi.org/classes) to register!
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
date: 'Jan 24th, 2024'
3+
id: usaco-spring-2024-tournament
4+
title: "USACO Spring 2024 Informatics Tournament Registration Open!"
5+
order: 8
6+
---
7+
8+
The USACO.Guide Spring 2024 Informatics Tournament will be held on March 2nd, 2024. Registration and details
9+
can be found [here!](https://forms.gle/4vHJeGiYGLgHRv4E6)

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,9 @@
191191
"twin": {
192192
"preset": "styled-components"
193193
}
194+
},
195+
"dependencies": {
196+
"clsx": "^2.1.0",
197+
"tailwind-merge": "^2.2.1"
194198
}
195199
}

src/components/Dashboard/Announcements.tsx

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
import * as React from 'react';
22
import { AnnouncementInfo } from '../../models/announcement';
3+
import { cn } from '../../utils/utils';
34
import Markdown from '../markdown/Markdown';
45

6+
/**
7+
*
8+
* @param announcements List of information given to render
9+
* @param className For overriding the default announcement container's styles
10+
* @param filterFn To be used in case you don't want to display all announcements
11+
* @returns
12+
*/
513
export default function Announcements({
614
announcements,
15+
className,
16+
filterFn,
717
}: {
818
announcements: AnnouncementInfo[];
19+
className?: string;
20+
filterFn?: (announcement: AnnouncementInfo) => boolean;
921
}) {
1022
return (
11-
<div className="flex overflow-x-auto sm:px-6 lg:px-8 py-4 grid lg:grid-cols-2 gap-8">
12-
{announcements.map(announcement => (
23+
<div
24+
className={cn(
25+
'flex overflow-x-auto sm:px-6 lg:px-8 py-4 grid lg:grid-cols-2 gap-8',
26+
className
27+
)}
28+
>
29+
{announcements.filter(filterFn ?? (() => true)).map(announcement => (
1330
<div
1431
className="bg-white dark:bg-gray-800 shadow transition sm:rounded-lg"
1532
key={announcement.id}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as React from 'react';
2+
3+
export default function Banner({
4+
text,
5+
registerLink,
6+
}: {
7+
text: string;
8+
registerLink: string;
9+
}) {
10+
return (
11+
<div className="relative isolate flex items-center gap-x-6 overflow-hidden bg-gray-50 dark:bg-[rgb(17_24_39)] px-6 py-2.5 sm:px-3.5 sm:before:flex-1">
12+
<div
13+
className="absolute left-[max(-7rem,calc(50%-52rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl"
14+
aria-hidden="true"
15+
>
16+
<div
17+
className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#ff80b5] to-[#9089fc] opacity-30"
18+
style={{
19+
clipPath:
20+
'polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)',
21+
}}
22+
/>
23+
</div>
24+
<div
25+
className="absolute left-[max(45rem,calc(50%+8rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl"
26+
aria-hidden="true"
27+
>
28+
<div
29+
className="aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#ff80b5] to-[#9089fc] opacity-30"
30+
style={{
31+
clipPath:
32+
'polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)',
33+
}}
34+
/>
35+
</div>
36+
<div className="flex flex-wrap items-center gap-x-4 gap-y-2">
37+
<p className="text-sm leading-6 text-gray-900 dark:text-white">
38+
{/* <strong className="font-semibold">GeneriCon 2023</strong> */}
39+
<svg
40+
viewBox="0 0 2 2"
41+
className="mx-2 inline h-0.5 w-0.5 fill-current"
42+
aria-hidden="true"
43+
>
44+
<circle cx={1} cy={1} r={1} />
45+
</svg>
46+
{text}
47+
</p>
48+
<a
49+
href={registerLink}
50+
className="flex-none rounded-full bg-gray-900 px-3.5 py-1 text-sm font-semibold text-white shadow-sm hover:bg-gray-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-900"
51+
>
52+
Register now <span aria-hidden="true">&rarr;</span>
53+
</a>
54+
</div>
55+
<div className="flex flex-1 justify-end">
56+
<span className="sr-only">Dismiss</span>
57+
</div>
58+
</div>
59+
);
60+
}

src/components/TopNavigationBar/TopNavigationBar.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import LogoSquare from '../LogoSquare';
3232
import MobileMenuButtonContainer from '../MobileMenuButtonContainer';
3333
import SectionsDropdown from '../SectionsDropdown';
3434
import { LoadingSpinner } from '../elements/LoadingSpinner';
35+
import Banner from './PrettyBanner';
3536
import { SearchModal } from './SearchModal';
3637
import { UserAvatarMenu } from './UserAvatarMenu';
3738

@@ -136,7 +137,11 @@ export default function TopNavigationBar({
136137
<>
137138
{!hidePromoBar && (
138139
<>
139-
<div className="relative bg-blue-600">
140+
<Banner
141+
text="Registration for Spring 2024 USACO classes now open!"
142+
registerLink="https://joincpi.org/classes"
143+
/>
144+
{/* <div className="relative bg-blue-600">
140145
<div className="max-w-screen-xl mx-auto py-3 px-3 sm:px-6 lg:px-8">
141146
<div className="pr-16 sm:text-center sm:px-16">
142147
<p className="font-medium text-white">
@@ -199,7 +204,7 @@ export default function TopNavigationBar({
199204
</p>
200205
</div>
201206
</div>
202-
</div>
207+
</div> */}
203208
</>
204209
)}
205210

src/pages/announcements.tsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { PageProps, graphql } from 'gatsby';
2+
import * as React from 'react';
3+
import Announcements from '../components/Dashboard/Announcements';
4+
import TopNavigationBar from '../components/TopNavigationBar/TopNavigationBar';
5+
import Layout from '../components/layout';
6+
import SEO from '../components/seo';
7+
import {
8+
AnnouncementInfo,
9+
graphqlToAnnouncementInfo,
10+
} from '../models/announcement';
11+
12+
export default function AnnouncementsPage(props: PageProps) {
13+
const { announcements } = props.data as any;
14+
const parsedAnnouncements: AnnouncementInfo[] = React.useMemo(() => {
15+
return announcements.edges.map(node =>
16+
graphqlToAnnouncementInfo(node.node)
17+
);
18+
}, []);
19+
20+
return (
21+
<Layout>
22+
<SEO title="Announcements" />
23+
<div className="min-h-screen bg-gray-100 dark:bg-dark-surface">
24+
<TopNavigationBar linkLogoToIndex={true} redirectToDashboard={true} />
25+
<h1 className="text-3xl font-bold leading-tight text-gray-900 dark:text-dark-high-emphasis text-center mx-auto mt-6">
26+
Announcements
27+
</h1>
28+
<main className="pb-12">
29+
<Announcements
30+
className="lg:grid-cols-1 max-w-xl px-12 mx-6 sm:mx-auto"
31+
announcements={parsedAnnouncements}
32+
/>
33+
</main>
34+
</div>
35+
</Layout>
36+
);
37+
}
38+
39+
export const pageQuery = graphql`
40+
query {
41+
announcements: allXdm(
42+
filter: { fileAbsolutePath: { regex: "/announcements/" } }
43+
sort: { order: DESC, fields: frontmatter___order }
44+
) {
45+
edges {
46+
node {
47+
frontmatter {
48+
title
49+
id
50+
date
51+
}
52+
body
53+
}
54+
}
55+
}
56+
}
57+
`;

src/pages/dashboard.tsx

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { graphql, PageProps } from 'gatsby';
1+
import { graphql, Link, PageProps } from 'gatsby';
22
import * as React from 'react';
33
import {
44
moduleIDToSectionMap,
@@ -207,10 +207,23 @@ export default function DashboardPage(props: PageProps) {
207207
<h1 className="text-3xl font-bold leading-tight text-gray-900 dark:text-dark-high-emphasis">
208208
Announcements
209209
</h1>
210+
<Link
211+
to="/announcements"
212+
className="hover:underline transition-all duration-300"
213+
>
214+
View all &rarr;
215+
</Link>
210216
</div>
211217
</header>
212218
<div className="max-w-7xl mx-auto mb-8">
213-
<Announcements announcements={parsedAnnouncements} />
219+
{/* Only show announcements in the current year by passing in a filter function */}
220+
<Announcements
221+
filterFn={announcement =>
222+
parseInt(announcement.date.split(', ')[1]) ===
223+
new Date().getFullYear()
224+
}
225+
announcements={parsedAnnouncements}
226+
/>
214227
</div>
215228
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8 lg:grid lg:grid-cols-2 lg:gap-8">
216229
{activeProblems.length > 0 && (

src/utils/utils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import clsx, { ClassValue } from 'clsx';
2+
import { twMerge } from 'tailwind-merge';
13
import MODULE_ORDERING from '../../content/ordering';
24
import { ModuleInfo } from '../models/module';
35

@@ -51,3 +53,5 @@ export function graphqlToModuleInfo(mdx: any): ModuleInfo {
5153
export function removeDuplicates<T>(arr: T[]): T[] {
5254
return [...new Map(arr.map(item => [JSON.stringify(item), item])).values()];
5355
}
56+
57+
export const cn = (...classes: ClassValue[]) => twMerge(clsx(...classes));

yarn.lock

+15-1
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,13 @@
17931793
dependencies:
17941794
regenerator-runtime "^0.14.0"
17951795

1796+
"@babel/runtime@^7.23.7":
1797+
version "7.23.9"
1798+
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
1799+
integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
1800+
dependencies:
1801+
regenerator-runtime "^0.14.0"
1802+
17961803
"@babel/template@^7.12.7", "@babel/template@^7.14.5":
17971804
version "7.16.0"
17981805
resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz"
@@ -9269,7 +9276,7 @@ clone@^2.1.1:
92699276
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
92709277
integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==
92719278

9272-
clsx@^2.0.0:
9279+
clsx@^2.0.0, clsx@^2.1.0:
92739280
version "2.1.0"
92749281
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
92759282
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
@@ -23006,6 +23013,13 @@ table@^6.0.9:
2300623013
string-width "^4.2.3"
2300723014
strip-ansi "^6.0.1"
2300823015

23016+
tailwind-merge@^2.2.1:
23017+
version "2.2.1"
23018+
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.1.tgz#3f10f296a2dba1d88769de8244fafd95c3324aeb"
23019+
integrity sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q==
23020+
dependencies:
23021+
"@babel/runtime" "^7.23.7"
23022+
2300923023
tailwindcss@^2.2.7:
2301023024
version "2.2.19"
2301123025
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.2.19.tgz"

0 commit comments

Comments
 (0)