Skip to content

Commit

Permalink
feat: init (internal) website
Browse files Browse the repository at this point in the history
  • Loading branch information
tri2820 committed Dec 5, 2024
1 parent 79217b7 commit 6ca19d9
Show file tree
Hide file tree
Showing 24 changed files with 790 additions and 0 deletions.
1 change: 1 addition & 0 deletions web/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GITHUB_ACCESS_TOKEN=
29 changes: 29 additions & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

dist
.solid
.output
.vercel
.netlify
.vinxi
app.config.timestamp_*.js

# Environment
.env
.env*.local

# dependencies
/node_modules

# IDEs and editors
/.idea
.project
.classpath
*.launch
.settings/

# Temp
gitignore

# System Files
.DS_Store
Thumbs.db
26 changes: 26 additions & 0 deletions web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Website

The website automatically reflects the status of pull requests and renders the articles from all pull requests into a single webpage, making it easy to search and give feedback. It is primarily for internal use.

## Develop

```bash
bun i
bun run dev
# npm would work too
```

## Deploy

While Cloudflare Pages is the preferred hosting platform, you can deploy to Vercel or any other platform with minimal adjustments. Alternatively, self-hosting is supported, and for that, you should refer to the SolidStart documentation.

Important:
- Ensure that web/.env exists and is populated with the necessary environment variables.
- `GITHUB_ACCESS_TOKEN` : A GitHub Personal Access Token is required to bypass GitHub's API rate limits

# Cache

Due to GitHub's API rate limits, the website utilizes a cache store to minimize API requests. Redeploying the website will clear out this cache.

# Support
Reach out to [email protected] if you have any questions.
3 changes: 3 additions & 0 deletions web/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineConfig } from "@solidjs/start/config";

export default defineConfig({});
Binary file added web/bun.lockb
Binary file not shown.
25 changes: 25 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "example-with-tailwindcss",
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start"
},
"dependencies": {
"@solidjs/router": "^0.15.0",
"@solidjs/start": "^1.0.10",
"autoprefixer": "^10.4.19",
"marked": "^15.0.3",
"postcss": "^8.4.38",
"solid-js": "^1.9.2",
"tailwindcss": "^3.4.3",
"vinxi": "^0.4.3"
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.15"
}
}
6 changes: 6 additions & 0 deletions web/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
15 changes: 15 additions & 0 deletions web/public/uni-basel-logo-svg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added web/public/unibas.ico
Binary file not shown.
13 changes: 13 additions & 0 deletions web/src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--background-rgb: 255, 255, 255;
--foreground-rgb: 0, 0, 0;
}

body {
background: rgb(var(--background-rgb));
color: rgb(var(--foreground-rgb));
}
29 changes: 29 additions & 0 deletions web/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import {
batch,
createEffect,
createSignal,
onMount,
Suspense,
untrack,
} from "solid-js";

import "./app.css";
import Nav from "./components/Nav";
import BottomNav from "./components/BottomNav";
export default function App() {
return (
<Router
root={(props) => (
<>
<Nav />
<Suspense>{props.children}</Suspense>
<BottomNav />
</>
)}
>
<FileRoutes />
</Router>
);
}
105 changes: 105 additions & 0 deletions web/src/components/Article.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Accessor, createSignal, For, onMount } from "solid-js";
import { marked } from "marked";
import { fetchRawFile, getPRFiles } from "~/server";
import { compareJaccardSimilarity, notEmpty } from "~/utils";
export default function Article(props: {
pull: PullRequest;
i: Accessor<number>;
}) {
const [html, setHTML] = createSignal<string>("");
const [image, setImage] = createSignal<string>("");

onMount(async () => {
// const user = props.pull.head.repo.owner.login;
// const repo = props.pull.head.repo.name;
// const branch = props.pull.head.ref;
const { files, cacheStatus } = await getPRFiles(
props.pull.number,
props.pull.updated_at
);
console.log("cacheStatus", cacheStatus, props.pull.number, files.length);

// Sometimes people mistakenly commit multiple files in a single pull request,
// We compare to find the most relevant folder w.r.t PR title
// Example: 2024/, folder code_obfuscation/ is more similar to 2024-spaghetti-code-obfuscation (PR title) than random_folder_name/
const folder = (path: string) => path.split("/").at(1);
const folders = files
.map((f) => {
const name = folder(f.filename);
if (name === undefined) return undefined;
return {
score: compareJaccardSimilarity(name, props.pull.title),
name,
};
})
.filter(notEmpty);

const mostRelevantFolder = folders.sort((a, b) => b.score - a.score)[0];

const markdownFile = files.find(
(f) =>
f.filename.toLowerCase().endsWith(".md") &&
folder(f.filename) == mostRelevantFolder.name
);
if (markdownFile === undefined) {
console.warn(
"No markdown file found for pull request",
props.pull.number
);
return;
}

const markdown = await fetchRawFile(markdownFile.raw_url);
const html = await marked(markdown);
setHTML(html);

const extensions = [".jpg", ".jpeg", ".png", ".svg"];
const images = files.map((f) => {
const index = extensions.findIndex(
(ext) =>
f.filename.toLowerCase().endsWith(ext) &&
folder(f.filename) == mostRelevantFolder.name
);
return {
...f,
score: index,
extension: extensions[index],
};
});
images.sort((a, b) => b.score - a.score);
setImage(images[0].raw_url);
});

return (
<div class="border">
<div class="px-4 py-2 bg-neutral-200 space-y-1">
<div>
<span class="font-bold">{props.i() + 1}.</span>{" "}
<a
target="_blank"
rel="noreferrer noopener"
class="hover:underline"
href={`https://github.com/unibas-tilics/tilics/pull/${props.pull.number}`}
>
#{props.pull.number} - {props.pull.title} by {props.pull.user.login}
</a>
</div>

<div class="flex flex-wrap gap-2">
<For each={props.pull.labels}>
{(l) => (
<div class="px-2 py-1 text-xs rounded-full bg-neutral-300">
<div class="z-20">{l.name}</div>
</div>
)}
</For>
</div>
</div>

<div class="space-y-16 px-4 py-2">
<img src={image()} class="w-2/3 " />
<div class="prose max-w-none" innerHTML={html()} />
</div>
</div>
);
}
36 changes: 36 additions & 0 deletions web/src/components/BottomNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default function BottomNav() {
return (
<div>
<div class="bg-[#2d373c] px-2 py-4 flex flex-col items-center text-white">
<div class="w-full max-w-4xl space-y-4 text-sm">
<a
class="hover:underline"
href="https://www.unibas.ch"
target="_blank"
rel="noopener noreferrer"
>
University of Basel
</a>{" "}
/{" "}
<a
class="hover:underline"
href="https://dmi.unibas.ch/"
target="_blank"
rel="noopener noreferrer"
>
DMI
</a>{" "}
/{" "}
<a
class="hover:underline"
href="https://tilics.dmi.unibas.ch/imprint"
target="_blank"
rel="noopener noreferrer"
>
Imprint
</a>
</div>
</div>
</div>
);
}
49 changes: 49 additions & 0 deletions web/src/components/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export default function Nav() {
return (
<div>
<div class="bg-[#a5d7d2] px-2 py-4 flex flex-col items-center">
<div class="w-full max-w-4xl space-y-4 ">
<a
href="https://www.unibas.ch"
target="_blank"
rel="noopener noreferrer"
>
<img src="/uni-basel-logo-svg.svg" alt="logo" width="160" />
</a>
<div class="lg:ml-16 text-sm">
<p>
<a
href="https://dmi.unibas.ch/"
target="_blank"
rel="noopener noreferrer"
>
Department
</a>
</p>
<p>
<a
href="https://dmi.unibas.ch/"
target="_blank"
rel="noopener noreferrer"
>
Mathematics and Computer Science
</a>
</p>
</div>
</div>
</div>

<div class="bg-[#d2ebe9] py-2 px-2 text-sm flex flex-col items-center">
<div class="w-full max-w-4xl space-y-4 ">
<a
href="https://github.com/unibas-tilics/tilics"
target="_blank"
rel="noopener noreferrer"
>
Things I learned in Computer Science
</a>
</div>
</div>
</div>
);
}
4 changes: 4 additions & 0 deletions web/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";

mount(() => <StartClient />, document.getElementById("app")!);
25 changes: 25 additions & 0 deletions web/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// @refresh reload
import { createHandler, StartServer } from "@solidjs/start/server";

export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>
Things I learned in Computer Science | University of Basel
</title>

<link rel="icon" href="/unibas.ico" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));
1 change: 1 addition & 0 deletions web/src/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="@solidjs/start/env" />
18 changes: 18 additions & 0 deletions web/src/routes/[...404].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { A } from "@solidjs/router";

export default function NotFound() {
return (
<main class="text-center mx-auto text-neutral-700 p-4">
<h1 class="max-6-xs text-6xl text-[#1b6f66] font-thin uppercase my-16">
Not Found
</h1>
<p class="mt-8">
The page you are looking for is not here. You can still go back to the{" "}
<A href="/" class="text-[#1b6f66]">
homepage
</A>{" "}
and try again.
</p>
</main>
);
}
Loading

0 comments on commit 6ca19d9

Please sign in to comment.