diff --git a/website/src/helpers/github.ts b/website/src/helpers/github.ts
new file mode 100644
index 0000000..5a3d1c9
--- /dev/null
+++ b/website/src/helpers/github.ts
@@ -0,0 +1,5 @@
+export const REPO_OWNER = 'acmucsd'
+export const REPO_NAME = 'acm-ai-workshops'
+export const DEFAULT_BRANCH = 'main'
+
+export const getGithubSlug = (fsPath: string[]) => `${REPO_OWNER}/${REPO_NAME}/blob/${DEFAULT_BRANCH}/${fsPath.map(encodeURIComponent).join('/')}`
\ No newline at end of file
diff --git a/website/src/layout/components/CategoryItemsGrid/styles.module.scss b/website/src/layout/components/CategoryItemsGrid/styles.module.scss
index 9d20013..bfc398b 100644
--- a/website/src/layout/components/CategoryItemsGrid/styles.module.scss
+++ b/website/src/layout/components/CategoryItemsGrid/styles.module.scss
@@ -1,6 +1,6 @@
.grid {
display: grid;
- grid-template-columns: repeat(auto-fill, min(100%, minmax(360px , 1fr))); // TODO
+ grid-template-columns: repeat(auto-fill, minmax(360px , 1fr)); // TODO
gap: 2rem;
.card {
diff --git a/website/src/layout/components/OpenElsewhereLinks/OpenInColab/index.tsx b/website/src/layout/components/OpenElsewhereLinks/OpenInColab/index.tsx
new file mode 100644
index 0000000..0d787d4
--- /dev/null
+++ b/website/src/layout/components/OpenElsewhereLinks/OpenInColab/index.tsx
@@ -0,0 +1,36 @@
+import { useMemo } from "react"
+import Link from "next/link"
+
+import { getGithubSlug } from "@/helpers/github"
+
+import s from "../styles.module.scss"
+
+const getColabUrl = (fsPath: string[]) => `https://colab.research.google.com/github/${getGithubSlug(fsPath)}`
+
+interface OpenInColabProps {
+ fsPath: string[]
+}
+
+export default function OpenInColab ({ fsPath }: OpenInColabProps) {
+ const colabUrl = useMemo(() => getColabUrl(fsPath), [fsPath])
+
+ return (
+
+ Open in Colab
+ {ExternalLinkSvg}
+
+ )
+}
+
+const ExternalLinkSvg = (
+
+)
\ No newline at end of file
diff --git a/website/src/layout/components/OpenElsewhereLinks/OpenInGithub/index.tsx b/website/src/layout/components/OpenElsewhereLinks/OpenInGithub/index.tsx
new file mode 100644
index 0000000..9b93baf
--- /dev/null
+++ b/website/src/layout/components/OpenElsewhereLinks/OpenInGithub/index.tsx
@@ -0,0 +1,39 @@
+import { useMemo } from "react"
+import Link from "next/link"
+
+import { getGithubSlug } from "@/helpers/github"
+
+import s from "../styles.module.scss"
+
+const getGithubUrl = (fsPath: string[]) => `https://github.com/${getGithubSlug(fsPath)}`
+
+interface OpenInGithubProps {
+ fsPath: string[]
+}
+
+export default function OpenInGithub ({ fsPath }: OpenInGithubProps) {
+ const githubUrl = useMemo(() => getGithubUrl(fsPath), [fsPath])
+
+ return (
+
+ {GithubSvg}
+ Open in GitHub
+
+ )
+}
+
+// TODO: we use github svg here (because we want to animate changing its color) but use img with svg source in header. the way we use it should be standardized
+const GithubSvg = (
+
+)
\ No newline at end of file
diff --git a/website/src/layout/components/OpenElsewhereLinks/index.tsx b/website/src/layout/components/OpenElsewhereLinks/index.tsx
new file mode 100644
index 0000000..d918bf0
--- /dev/null
+++ b/website/src/layout/components/OpenElsewhereLinks/index.tsx
@@ -0,0 +1,16 @@
+import s from "./styles.module.scss"
+import OpenInColab from "./OpenInColab"
+import OpenInGithub from "./OpenInGithub"
+
+interface OpenElsewhereLinksProps {
+ fsPath: string[]
+}
+
+export default function OpenElsewhereLinks ({ fsPath }: OpenElsewhereLinksProps) {
+ return (
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/website/src/layout/components/OpenElsewhereLinks/styles.module.scss b/website/src/layout/components/OpenElsewhereLinks/styles.module.scss
new file mode 100644
index 0000000..3dff27e
--- /dev/null
+++ b/website/src/layout/components/OpenElsewhereLinks/styles.module.scss
@@ -0,0 +1,38 @@
+@use "@/styles/colors";
+
+.links {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.5rem 2rem;
+ flex-wrap: wrap;
+}
+
+.link {
+ padding: 0.5rem;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ gap: 0.25em;
+
+ transition: color 400ms ease;
+ &:hover {
+ color: colors.$red;
+
+ & .svg {
+ fill: colors.$red;
+ }
+ }
+
+ .label, .svg {
+ flex: 0 0 auto;
+ }
+
+ .svg {
+ width: 1em;
+ height: 1em;
+
+ fill: currentColor;
+ transition: fill 400ms ease;
+ }
+}
\ No newline at end of file
diff --git a/website/src/layout/components/OpenInColab/styles.module.scss.d.ts b/website/src/layout/components/OpenElsewhereLinks/styles.module.scss.d.ts
similarity index 83%
rename from website/src/layout/components/OpenInColab/styles.module.scss.d.ts
rename to website/src/layout/components/OpenElsewhereLinks/styles.module.scss.d.ts
index 0400e60..2011ea9 100644
--- a/website/src/layout/components/OpenInColab/styles.module.scss.d.ts
+++ b/website/src/layout/components/OpenElsewhereLinks/styles.module.scss.d.ts
@@ -1,8 +1,10 @@
// AUTOGENERATED FILE -- DO NOT EDIT DIRECTLY
declare namespace StylesModuleScssNamespace {
export interface IStylesModuleScss {
- external: string;
+ label: string;
link: string;
+ links: string;
+ svg: string;
}
}
diff --git a/website/src/layout/components/OpenInColab/index.tsx b/website/src/layout/components/OpenInColab/index.tsx
deleted file mode 100644
index 97feb8c..0000000
--- a/website/src/layout/components/OpenInColab/index.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { useMemo } from "react"
-import Link from "next/link"
-
-import s from "./styles.module.scss"
-
-const REPO_OWNER = 'acmucsd'
-const REPO_NAME = 'acm-ai-workshops'
-const DEFAULT_BRANCH = 'main'
-const getColabUrl = (fsPath: string[]) => `https://colab.research.google.com/github/${REPO_OWNER}/${REPO_NAME}/blob/${DEFAULT_BRANCH}/${fsPath.map(encodeURIComponent).join('/')}`
-
-interface OpenInColabProps {
- fsPath: string[]
-}
-
-const OpenInColab = ({ fsPath }: OpenInColabProps) => {
- const colabUrl = useMemo(() => getColabUrl(fsPath), [fsPath])
-
- return (
-
- Open in Colab
-
-
- )
-}
-
-export default OpenInColab
\ No newline at end of file
diff --git a/website/src/layout/components/OpenInColab/styles.module.scss b/website/src/layout/components/OpenInColab/styles.module.scss
deleted file mode 100644
index 5a038b4..0000000
--- a/website/src/layout/components/OpenInColab/styles.module.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-@use "@/styles/colors";
-
-.link {
- padding: 0.5rem;
- font-weight: 600;
-
- transition: color 400ms ease;
-
- &:hover {
- color: colors.$red;
- }
-}
-
-.external {
- display: inline-block;
- width: 1em;
- height: 1em;
- text-align: baseline;
- margin-left: 0.25em;
-}
\ No newline at end of file
diff --git a/website/src/layout/pages/CategoryPage/index.tsx b/website/src/layout/pages/CategoryPage/index.tsx
index 5fa7cf6..a7bb754 100644
--- a/website/src/layout/pages/CategoryPage/index.tsx
+++ b/website/src/layout/pages/CategoryPage/index.tsx
@@ -10,8 +10,10 @@ import CategoryItemsGrid from "@/layout/components/CategoryItemsGrid";
import PageProvider from "@/layout/context/Page";
import type { CategoryPageProps } from "@/layout/pages/types";
+import BeforeMarkdown from "@/layout/components/BeforeMarkdown";
+import OpenInGithub from "@/layout/components/OpenElsewhereLinks/OpenInGithub";
-export default function CategoryPage ({ slug, sidebar, items }: CategoryPageProps) {
+export default function CategoryPage ({ slug, sidebar, items, fsPath }: CategoryPageProps) {
const { asPath } = useRouter()
return (
@@ -21,6 +23,9 @@ export default function CategoryPage ({ slug, sidebar, items }: CategoryPageProp
+
+
+
diff --git a/website/src/layout/pages/DocPage/index.tsx b/website/src/layout/pages/DocPage/index.tsx
index 801a58f..2d1f596 100644
--- a/website/src/layout/pages/DocPage/index.tsx
+++ b/website/src/layout/pages/DocPage/index.tsx
@@ -9,7 +9,7 @@ import ContentWrapper from "@/layout/components/ContentWrapper";
import ContentContainer from "@/layout/components/ContentContainer";
import TocContainer from "@/layout/components/TocContainer";
import BeforeMarkdown from "@/layout/components/BeforeMarkdown";
-import OpenInColab from "@/layout/components/OpenInColab";
+import OpenElsewhereLinks from "@/layout/components/OpenElsewhereLinks";
import MarkdownWrapper from "@/layout/components/MarkdownWrapper";
import PageProvider from "@/layout/context/Page";
@@ -31,7 +31,7 @@ export default function DocPage ({ source, slug, fsPath, sidebar, toc }: DocPage
-
+
diff --git a/website/src/pages/workshops/[...slug].tsx b/website/src/pages/workshops/[...slug].tsx
index 46b3193..09afdbc 100644
--- a/website/src/pages/workshops/[...slug].tsx
+++ b/website/src/pages/workshops/[...slug].tsx
@@ -56,6 +56,7 @@ export const getStaticProps: GetStaticProps = async ({ params }) => {
return {
type: 'category',
items: flattenedItems,
+ fsPath: entry.fsPath,
} as Omit;
case 'file':