diff --git a/.gitignore b/.gitignore
index c95a43e..e02be2b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@ pnpm-debug.log*
# macOS-specific files
.DS_Store
dist
+
+./friends-best
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d00d935
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+# Friends Best
+A fan website for the Netflix series "Young Royals".
+
+## Contributing
+I suggest using [Just](https://github.com/casey/just) to help with building
+local changes. [PNPM](https://pnpm.io) is used for the package manager for the
+frontend and the server is written in [Go](https://go.dev).
+### Build Frontend
+```sh
+just build-fe
+```
+or
+```sh
+cd fe
+pnpm build
+```
+
+### Build server
+```sh
+just build-server
+```
+or
+```sh
+go build ./server
+```
+
+### Build all
+```sh
+just build-all
+```
+
+### Build and Run all
+```sh
+just serve
+```
diff --git a/fe/src/assets/styles/_colours.scss b/fe/src/assets/styles/_colours.scss
new file mode 100644
index 0000000..e7e3ad5
--- /dev/null
+++ b/fe/src/assets/styles/_colours.scss
@@ -0,0 +1,4 @@
+$bg-colour-light: rgb(187, 187, 187);
+$accent-colour-light: rgb(24, 96, 231);
+$filter-accent-colour-light: invert(34%) sepia(96%) saturate(4970%) hue-rotate(216deg) brightness(95%) contrast(91%);
+$filter-link-colour-dark: invert(99%) sepia(52%) saturate(532%) hue-rotate(308deg) brightness(100%) contrast(95%);
diff --git a/fe/src/assets/styles/globals.scss b/fe/src/assets/styles/globals.scss
new file mode 100644
index 0000000..f8fa70b
--- /dev/null
+++ b/fe/src/assets/styles/globals.scss
@@ -0,0 +1,20 @@
+@use 'colours';
+@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;700&display=swap');
+
+body {
+ font-family: 'Ubuntu', sans-serif !important;
+ background-color: wheat !important;
+}
+
+.container {
+ min-height: 80vh;
+ padding: 0 0.5rem;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.title {
+ font-size: 3rem;
+}
diff --git a/fe/src/assets/styles/index.scss b/fe/src/assets/styles/index.scss
new file mode 100644
index 0000000..3ed9fbf
--- /dev/null
+++ b/fe/src/assets/styles/index.scss
@@ -0,0 +1,3 @@
+@use 'colours';
+
+
diff --git a/fe/src/components/Card.astro b/fe/src/components/Card.astro
new file mode 100644
index 0000000..ee57d4d
--- /dev/null
+++ b/fe/src/components/Card.astro
@@ -0,0 +1,62 @@
+---
+export interface Props {
+ title: string;
+ body: string;
+ href: string;
+}
+
+const { href, title, body } = Astro.props;
+---
+
+
+
+
+ {title}
+ →
+
+
+ {body}
+
+
+
+
diff --git a/fe/src/components/LinkCard.astro b/fe/src/components/LinkCard.astro
new file mode 100644
index 0000000..388d20a
--- /dev/null
+++ b/fe/src/components/LinkCard.astro
@@ -0,0 +1,58 @@
+---
+export interface Props {
+ title: string;
+ to: string;
+}
+
+const { to, title } = Astro.props;
+
+const isExternal = to.startsWith('http');
+---
+{ isExternal == true ? (
+
+ {title} →
+
+) : (
+
+ {title} →
+
+)
+}
+
diff --git a/fe/src/components/NavBar.astro b/fe/src/components/NavBar.astro
new file mode 100644
index 0000000..50481f9
--- /dev/null
+++ b/fe/src/components/NavBar.astro
@@ -0,0 +1,66 @@
+---
+export interface Props {
+ links: {
+ to: string;
+ name: string;
+ img: {
+ src: string;
+ alt: string;
+ }
+ }[]
+}
+
+const { links } = Astro.props;
+---
+
+
+{ links.map(link => (
+
+ ))
+}
+
+
+
diff --git a/fe/src/components/TimeFormat.vue b/fe/src/components/TimeFormat.vue
new file mode 100644
index 0000000..cd07d9e
--- /dev/null
+++ b/fe/src/components/TimeFormat.vue
@@ -0,0 +1,40 @@
+
+
+
+
+ {{ `` }}
+
+
+ to get
+
+
+ {{Intl.DateTimeFormat(Intl.Locale, format).format(crntTime) + ' '}}
+
+
+
+
\ No newline at end of file
diff --git a/fe/src/components/TimeZone.vue b/fe/src/components/TimeZone.vue
new file mode 100644
index 0000000..a060625
--- /dev/null
+++ b/fe/src/components/TimeZone.vue
@@ -0,0 +1,4 @@
+
+
+ {{Intl.DateTimeFormat().resolvedOptions().timeZone}}
+
\ No newline at end of file
diff --git a/fe/src/components/UnixTime.vue b/fe/src/components/UnixTime.vue
new file mode 100644
index 0000000..2c258e1
--- /dev/null
+++ b/fe/src/components/UnixTime.vue
@@ -0,0 +1,9 @@
+
+
+
+ The current time in Unix Epoch: {{ Math.floor(crntTime / 1000) }}
or {{crntTime}}
in Unix millis
+
\ No newline at end of file
diff --git a/fe/src/env.d.ts b/fe/src/env.d.ts
index 8c34fb4..f964fe0 100644
--- a/fe/src/env.d.ts
+++ b/fe/src/env.d.ts
@@ -1 +1 @@
-///
\ No newline at end of file
+///
diff --git a/fe/src/layouts/Layout.astro b/fe/src/layouts/Layout.astro
new file mode 100644
index 0000000..b3c8d51
--- /dev/null
+++ b/fe/src/layouts/Layout.astro
@@ -0,0 +1,108 @@
+---
+import NavBar from '../components/NavBar.astro';
+
+export interface Props {
+ title: string;
+ navLinks: {
+ to: string;
+ name: string;
+ img: {
+ src: string;
+ alt: string;
+ }
+ }[] | undefined
+}
+
+const { title, navLinks } = Astro.props;
+import { ViewTransitions } from 'astro:transitions';
+---
+
+
+
+
+
+
+
+
+
+ {title}
+
+
+ { navLinks != undefined ? (
+
+ ) : ()
+ }
+
+
+
+
diff --git a/fe/src/pages/index.astro b/fe/src/pages/index.astro
new file mode 100644
index 0000000..bb12eb2
--- /dev/null
+++ b/fe/src/pages/index.astro
@@ -0,0 +1,39 @@
+---
+import Layout from '../layouts/Layout.astro';
+import LinkCard from '../components/LinkCard.astro';
+---
+
+
+
+
+
Vänner Bästa
+
+
+ A Young Royals fan website with links to different discussion
+ spaces.
+
+
It's official! Series 3 is coming!
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/fe/src/pages/utilities/birthdays.astro b/fe/src/pages/utilities/birthdays.astro
new file mode 100644
index 0000000..aa9fae8
--- /dev/null
+++ b/fe/src/pages/utilities/birthdays.astro
@@ -0,0 +1,42 @@
+---
+import TimeZone from "../../components/TimeZone.vue";
+import Layout from "../../layouts/Layout.astro";
+
+const navLinks = [
+ {
+ img: {
+ src: '/icons/arrow-left.svg',
+ alt: 'Back to Utilities',
+ },
+ to: '/utilities',
+ name: "Utilities",
+ },
+ {
+ img: {
+ src: '/icons/home.svg',
+ alt: 'Go Home',
+ },
+ to: '/',
+ name: "Home",
+ },
+];
+---
+
+
+
+
+
Birthdays
+
+ Discord bots are changing.
+ This means that we can no longer provide you with the command to set
+ your birthday.
+ Instead, this page now gives you your timezone for use with Discord
+ bots.
+
+
+ Your timezone:
+
+
+
+
+
diff --git a/fe/src/pages/utilities/index.astro b/fe/src/pages/utilities/index.astro
new file mode 100644
index 0000000..385c3e5
--- /dev/null
+++ b/fe/src/pages/utilities/index.astro
@@ -0,0 +1,27 @@
+---
+import LinkCard from "../../components/LinkCard.astro";
+import NavBar from "../../components/NavBar.astro";
+import Layout from '../../layouts/Layout.astro';
+
+const navLinks = [
+ {
+ img: {
+ src: '/icons/home.svg',
+ alt: 'Go Home',
+ },
+ to: '/',
+ name: "Home",
+ },
+];
+---
+
+
+
+
Utilities for the Discord Server
+
+
+
+
+
+
+
diff --git a/fe/src/pages/utilities/time.astro b/fe/src/pages/utilities/time.astro
new file mode 100644
index 0000000..6db0585
--- /dev/null
+++ b/fe/src/pages/utilities/time.astro
@@ -0,0 +1,79 @@
+---
+
+import NavBar from "../../components/NavBar.astro";
+import TimeZone from "../../components/TimeZone.vue";
+import Layout from "../../layouts/Layout.astro";
+import TimeFormat from "../../components/TimeFormat.vue";
+import UnixTime from "../../components/UnixTime.vue";
+
+const navLinks = [
+ {
+ img: {
+ src: '/icons/arrow-left.svg',
+ alt: 'Back to Utilities',
+ },
+ to: '/utilities',
+ name: 'Utilities',
+ },
+ {
+ img: {
+ src: '/icons/home.svg',
+ alt: 'Go Home',
+ },
+ to: '/',
+ name: 'Home',
+ },
+];
+---
+
+
+
+
+
Time Utilities
+
+ Your current timezone:
+
+
+
+
+
+
+ To format the time for Discord, you can use:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/friends-best b/friends-best
new file mode 100755
index 0000000..c17fc80
Binary files /dev/null and b/friends-best differ
diff --git a/justfile b/justfile
index 918da49..c42944a 100644
--- a/justfile
+++ b/justfile
@@ -10,3 +10,11 @@ build-all:
git:
git add -A && git commit -sS && git push
+
+serve: build-all
+ ./friends-best
+
+go-tidy:
+ cd ./server && go mod tidy && cd ..
+go-get MOD:
+ cd ./server && go get {{MOD}} && cd ..
diff --git a/server/go.mod b/server/go.mod
index e2e916e..c0b4e74 100644
--- a/server/go.mod
+++ b/server/go.mod
@@ -1,3 +1,10 @@
module git.ludoviko.ch/lucxjo/friends-best
go 1.21.6
+
+require (
+ github.com/gorilla/mux v1.8.1
+ github.com/sirupsen/logrus v1.9.3
+)
+
+require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
diff --git a/server/go.sum b/server/go.sum
new file mode 100644
index 0000000..f857cfc
--- /dev/null
+++ b/server/go.sum
@@ -0,0 +1,17 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/server/main.go b/server/main.go
index 38dd16d..86339ae 100644
--- a/server/main.go
+++ b/server/main.go
@@ -1,3 +1,17 @@
package main
-func main() {}
+import (
+ "github.com/gorilla/mux"
+ "net/http"
+ log "github.com/sirupsen/logrus"
+)
+
+func main() {
+ r := mux.NewRouter()
+
+ r.PathPrefix("/").Handler(http.FileServer(http.Dir("./dist")))
+
+ if err := http.ListenAndServe(":3000", r); err != nil {
+ log.Fatalf("failed to start server: %v", err)
+ }
+}