init
This commit is contained in:
commit
17a815d185
29
.gitignore
vendored
Normal file
29
.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
dist
|
||||
.solid
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
netlify
|
||||
.vinxi
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env*.local
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
*.launch
|
||||
.settings/
|
||||
|
||||
# Temp
|
||||
gitignore
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM node:alpine
|
||||
|
||||
EXPOSE 3000
|
||||
WORKDIR /app
|
||||
|
||||
ADD . .
|
||||
|
||||
RUN npm ci\
|
||||
&& npm run build
|
||||
|
||||
CMD ["npm", "run", "start"]
|
32
README.md
Normal file
32
README.md
Normal file
@ -0,0 +1,32 @@
|
||||
# SolidStart
|
||||
|
||||
Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com);
|
||||
|
||||
## Creating a project
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm init solid@latest
|
||||
|
||||
# create a new project in my-app
|
||||
npm init solid@latest my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Solid apps are built with _presets_, which optimise your project for deployment to different environments.
|
||||
|
||||
By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`.
|
||||
|
||||
## This project was created with the [Solid CLI](https://solid-cli.netlify.app)
|
19
app.config.timestamp_1715689320255.js
Normal file
19
app.config.timestamp_1715689320255.js
Normal file
@ -0,0 +1,19 @@
|
||||
// app.config.ts
|
||||
import { defineConfig } from "@solidjs/start/config";
|
||||
import pkg from "@vinxi/plugin-mdx";
|
||||
var { default: mdx } = pkg;
|
||||
var app_config_default = defineConfig({
|
||||
extensions: ["mdx", "md"],
|
||||
vite: {
|
||||
plugins: [
|
||||
mdx.withImports({})({
|
||||
jsx: true,
|
||||
jsxImportSource: "solid-js",
|
||||
providerImportSource: "solid-mdx"
|
||||
})
|
||||
]
|
||||
}
|
||||
});
|
||||
export {
|
||||
app_config_default as default
|
||||
};
|
19
app.config.timestamp_1715689323984.js
Normal file
19
app.config.timestamp_1715689323984.js
Normal file
@ -0,0 +1,19 @@
|
||||
// app.config.ts
|
||||
import { defineConfig } from "@solidjs/start/config";
|
||||
import pkg from "@vinxi/plugin-mdx";
|
||||
var { default: mdx } = pkg;
|
||||
var app_config_default = defineConfig({
|
||||
extensions: ["mdx", "md"],
|
||||
vite: {
|
||||
plugins: [
|
||||
mdx.withImports({})({
|
||||
jsx: true,
|
||||
jsxImportSource: "solid-js",
|
||||
providerImportSource: "solid-mdx"
|
||||
})
|
||||
]
|
||||
}
|
||||
});
|
||||
export {
|
||||
app_config_default as default
|
||||
};
|
17
app.config.ts
Normal file
17
app.config.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { defineConfig } from "@solidjs/start/config";
|
||||
/* @ts-ignore */
|
||||
import pkg from "@vinxi/plugin-mdx";
|
||||
|
||||
const { default: mdx } = pkg;
|
||||
export default defineConfig({
|
||||
extensions: ["mdx", "md"],
|
||||
vite: {
|
||||
plugins: [
|
||||
mdx.withImports({})({
|
||||
jsx: true,
|
||||
jsxImportSource: "solid-js",
|
||||
providerImportSource: "solid-mdx",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
10290
package-lock.json
generated
Normal file
10290
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
package.json
Normal file
27
package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "example-with-tailwindcss",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vinxi dev",
|
||||
"build": "vinxi build",
|
||||
"start": "vinxi start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^2.3.0",
|
||||
"@solidjs/router": "^0.13.3",
|
||||
"@solidjs/start": "^1.0.0-rc.1",
|
||||
"@vinxi/plugin-mdx": "^3.7.1",
|
||||
"apexcharts": "^3.49.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"daisyui": "^4.11.1",
|
||||
"postcss": "^8.4.38",
|
||||
"solid-apexcharts": "^0.3.4",
|
||||
"solid-js": "^1.8.17",
|
||||
"solid-mdx": "^0.0.7",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"vinxi": "^0.3.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
6
postcss.config.cjs
Normal file
6
postcss.config.cjs
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
12
public/assets/ddix-logo.svg
Normal file
12
public/assets/ddix-logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 9.3 KiB |
BIN
public/dresden.webp
Normal file
BIN
public/dresden.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 KiB |
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 664 B |
BIN
public/fonts/ubuntu-v20-latin-300.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-300.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-300italic.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-300italic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-500.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-500.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-500italic.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-500italic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-700.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-700.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-700italic.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-700italic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-italic.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-italic.woff2
Normal file
Binary file not shown.
BIN
public/fonts/ubuntu-v20-latin-regular.woff2
Normal file
BIN
public/fonts/ubuntu-v20-latin-regular.woff2
Normal file
Binary file not shown.
16
src/app.css
Normal file
16
src/app.css
Normal file
@ -0,0 +1,16 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
h1 {
|
||||
@apply text-5xl font-bold;
|
||||
}
|
||||
h2 {
|
||||
@apply text-4xl font-bold;
|
||||
}
|
||||
h3 {
|
||||
@apply text-3xl font-bold;
|
||||
}
|
||||
h3 {
|
||||
@apply text-2xl font-bold;
|
||||
}
|
27
src/app.tsx
Normal file
27
src/app.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { Router } from "@solidjs/router";
|
||||
import { FileRoutes } from "@solidjs/start/router";
|
||||
import { Suspense } from "solid-js";
|
||||
import Nav from "~/components/Nav";
|
||||
import Footer from "./components/Footer";
|
||||
import "./app.css";
|
||||
import "./fonts.css";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Router
|
||||
root={(props) => (
|
||||
<>
|
||||
<div class="min-h-screen flex flex-col justify-between">
|
||||
<div>
|
||||
<Nav />
|
||||
<Suspense>{props.children}</Suspense>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
<FileRoutes />
|
||||
</Router>
|
||||
);
|
||||
}
|
13
src/components/Counter.tsx
Normal file
13
src/components/Counter.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
export default function Counter() {
|
||||
const [count, setCount] = createSignal(0);
|
||||
return (
|
||||
<button
|
||||
class="w-[200px] rounded-full bg-gray-100 border-2 border-gray-300 focus:border-gray-400 active:border-gray-400 px-[2rem] py-[1rem]"
|
||||
onClick={() => setCount(count() + 1)}
|
||||
>
|
||||
Clicks: {count()}
|
||||
</button>
|
||||
);
|
||||
}
|
54
src/components/DNSChart.tsx
Normal file
54
src/components/DNSChart.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { SolidApexCharts } from "solid-apexcharts";
|
||||
|
||||
export default ({ data }) => {
|
||||
return (
|
||||
<SolidApexCharts
|
||||
type="area"
|
||||
options={{
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: (val) => (val).toFixed(0),
|
||||
},
|
||||
title: {
|
||||
text: "Queries/s",
|
||||
},
|
||||
logarithmic: true,
|
||||
forceNiceScale: true,
|
||||
},
|
||||
xaxis: {
|
||||
min: data.start,
|
||||
max: data.end,
|
||||
type: "datetime",
|
||||
},
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
fill: {
|
||||
type: "gradient",
|
||||
gradient: {
|
||||
type: "horizontal",
|
||||
shadeIntensity: 1,
|
||||
inverseColors: false,
|
||||
opacityFrom: 0.5,
|
||||
opacityTo: 0,
|
||||
stops: [0, 90, 100],
|
||||
},
|
||||
},
|
||||
}}
|
||||
series={[
|
||||
{
|
||||
name: "Traffic",
|
||||
data: data.data.map(([time, value]) => [time * 1000, value]),
|
||||
color: "#209680",
|
||||
type: "area",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
// <div>{JSON.stringify(data)}</div>
|
||||
);
|
||||
};
|
33
src/components/Footer.tsx
Normal file
33
src/components/Footer.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useLocation } from "@solidjs/router";
|
||||
import { A } from "@solidjs/router";
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer class="footer p-10 bg-base-300 text-base-content">
|
||||
<aside>
|
||||
<img src="/assets/ddix-logo.svg" class="h-16" />
|
||||
<p>© 2024 DD-IX Dresden Internet Exchange e.V.</p>
|
||||
</aside>
|
||||
<nav>
|
||||
<h6 class="footer-title">Services</h6>
|
||||
<a class="link link-hover">Branding</a>
|
||||
<a class="link link-hover">Design</a>
|
||||
<a class="link link-hover">Marketing</a>
|
||||
<a class="link link-hover">Advertisement</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Company</h6>
|
||||
<a class="link link-hover">About us</a>
|
||||
<a class="link link-hover">Contact</a>
|
||||
<a class="link link-hover">Jobs</a>
|
||||
<a class="link link-hover">Press kit</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Legal</h6>
|
||||
<a class="link link-hover">Terms of use</a>
|
||||
<a class="link link-hover">Privacy policy</a>
|
||||
<a class="link link-hover">Cookie policy</a>
|
||||
</nav>
|
||||
</footer>
|
||||
);
|
||||
}
|
72
src/components/Nav.tsx
Normal file
72
src/components/Nav.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import { useLocation } from "@solidjs/router";
|
||||
import { A } from "@solidjs/router";
|
||||
|
||||
export default function Nav() {
|
||||
const location = useLocation();
|
||||
const active = (path: string) =>
|
||||
path == location.pathname
|
||||
? "border-sky-600"
|
||||
: "border-transparent hover:border-sky-600";
|
||||
return (
|
||||
<header class="p-4 fixed w-full top-0 z-10">
|
||||
<div class="navbar backdrop-blur-md bg-base-200/50 shadow-xl">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h8m-8 6h16"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52"
|
||||
>
|
||||
<li>
|
||||
<a>Item 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>Parent</a>
|
||||
<ul class="p-2">
|
||||
<li>
|
||||
<a>Submenu 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>Submenu 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a>Item 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<A class="btn btn-ghost text-xl" href="/">
|
||||
<img src="/assets/ddix-logo.svg" class="h-full p-2" />
|
||||
</A>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<A class="btn btn-ghost mr-2" href="/statistics">
|
||||
Stats
|
||||
</A>
|
||||
<A class="btn btn-ghost mr-2" href="/news">
|
||||
News
|
||||
</A>
|
||||
<A class="btn btn-ghost" href="/network">
|
||||
Network
|
||||
</A>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
49
src/components/NewsList.tsx
Normal file
49
src/components/NewsList.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
import { cache, createAsync, A, type RouteDefinition } from "@solidjs/router";
|
||||
|
||||
const getNewsList = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/news/en").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "news-list");
|
||||
|
||||
const getNewsTags = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/news/keywords").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "news-tags");
|
||||
|
||||
export const route = {
|
||||
load: () => {
|
||||
getNewsList();
|
||||
getNewsTags();
|
||||
},
|
||||
} satisfies RouteDefinition;
|
||||
|
||||
export const NewsList = ({ limit }: { limit: number }) => {
|
||||
const newsList = createAsync(() => getNewsList());
|
||||
const tags = createAsync(() => getNewsTags());
|
||||
|
||||
return (
|
||||
<For each={newsList()?.slice(0, limit)}>
|
||||
{(post) => (
|
||||
<A href={`/news/${post.slug}`}>
|
||||
<figure class="card md:card-side bg-base-100 shadow-xl mt-4">
|
||||
<img
|
||||
src={`https://content.dd-ix.net/news/assets/${post.image}`}
|
||||
alt={post.title}
|
||||
class="md:w-48 object-cover"
|
||||
/>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{post.title}</h2>
|
||||
<p>{post.published}</p>
|
||||
<p>{post.description}</p>
|
||||
</div>
|
||||
</figure>
|
||||
</A>
|
||||
)}
|
||||
</For>
|
||||
);
|
||||
};
|
54
src/components/TrafficChart.tsx
Normal file
54
src/components/TrafficChart.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { SolidApexCharts } from "solid-apexcharts";
|
||||
|
||||
export default ({ data }) => {
|
||||
return (
|
||||
<SolidApexCharts
|
||||
type="line"
|
||||
options={{
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: (val) => (val / 1000).toFixed(0),
|
||||
},
|
||||
title: {
|
||||
text: "Traffic in kb/s",
|
||||
},
|
||||
logarithmic: true,
|
||||
forceNiceScale: true,
|
||||
},
|
||||
xaxis: {
|
||||
min: data.start,
|
||||
max: data.end,
|
||||
type: "datetime",
|
||||
},
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
fill: {
|
||||
type: "gradient",
|
||||
gradient: {
|
||||
type: "horizontal",
|
||||
shadeIntensity: 1,
|
||||
inverseColors: false,
|
||||
opacityFrom: 0.5,
|
||||
opacityTo: 0,
|
||||
stops: [0, 90, 100],
|
||||
},
|
||||
},
|
||||
}}
|
||||
series={[
|
||||
{
|
||||
name: "Traffic",
|
||||
data: data.data.map(([time, value]) => [time * 1000, value]),
|
||||
color: "#209680",
|
||||
type: "area",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
// <div>{JSON.stringify(data)}</div>
|
||||
);
|
||||
};
|
4
src/entry-client.tsx
Normal file
4
src/entry-client.tsx
Normal file
@ -0,0 +1,4 @@
|
||||
// @refresh reload
|
||||
import { mount, StartClient } from "@solidjs/start/client";
|
||||
|
||||
mount(() => <StartClient />, document.getElementById("app")!);
|
21
src/entry-server.tsx
Normal file
21
src/entry-server.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
// @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" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
{assets}
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">{children}</div>
|
||||
{scripts}
|
||||
</body>
|
||||
</html>
|
||||
)}
|
||||
/>
|
||||
));
|
71
src/fonts.css
Normal file
71
src/fonts.css
Normal file
@ -0,0 +1,71 @@
|
||||
/* ubuntu-300 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url("/fonts/ubuntu-v20-latin-300.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-300italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: url("/fonts/ubuntu-v20-latin-300italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-regular - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("/fonts/ubuntu-v20-latin-regular.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url("/fonts/ubuntu-v20-latin-italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-500 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url("/fonts/ubuntu-v20-latin-500.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-500italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
src: url("/fonts/ubuntu-v20-latin-500italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-700 - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url("/fonts/ubuntu-v20-latin-700.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
||||
|
||||
/* ubuntu-700italic - latin */
|
||||
@font-face {
|
||||
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
|
||||
font-family: "Ubuntu";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("/fonts/ubuntu-v20-latin-700italic.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
|
||||
}
|
1
src/global.d.ts
vendored
Normal file
1
src/global.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="@solidjs/start/env" />
|
9
src/routes/[...404].tsx
Normal file
9
src/routes/[...404].tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { A } from "@solidjs/router";
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<main class="text-center p-4">
|
||||
<h1>Not Found :/</h1>
|
||||
</main>
|
||||
);
|
||||
}
|
25
src/routes/about.tsx
Normal file
25
src/routes/about.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import Counter from "~/components/Counter";
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
<main class="text-center mx-auto text-gray-700 p-4">
|
||||
<h1 class="max-6-xs text-6xl text-sky-700 font-thin uppercase my-16">About Page</h1>
|
||||
<Counter />
|
||||
<p class="mt-8">
|
||||
Visit{" "}
|
||||
<a href="https://solidjs.com" target="_blank" class="text-sky-600 hover:underline">
|
||||
solidjs.com
|
||||
</a>{" "}
|
||||
to learn how to build Solid apps.
|
||||
</p>
|
||||
<p class="my-4">
|
||||
<A href="/" class="text-sky-600 hover:underline">
|
||||
Home
|
||||
</A>
|
||||
{" - "}
|
||||
<span>About Page</span>
|
||||
</p>
|
||||
</main>
|
||||
);
|
||||
}
|
68
src/routes/index.mdx
Normal file
68
src/routes/index.mdx
Normal file
@ -0,0 +1,68 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import { NewsList } from "~/components/NewsList"
|
||||
|
||||
<main>
|
||||
|
||||
<div
|
||||
class="hero h-[70vh] min-h-96"
|
||||
style="background-image: url(/dresden.webp);"
|
||||
>
|
||||
<div class="hero-overlay bg-opacity-40 backdrop-blur-sm"></div>
|
||||
<div class="hero-content text-center text-neutral-content">
|
||||
<div class="max-w-xl">
|
||||
<h1 class="text-5xl md:text-7xl">Keep Local<br/>Traffic Local</h1>
|
||||
<div class="divider"></div>
|
||||
<div class="flex gap-2 justify-center">
|
||||
<A href="/peering" class="btn btn-primary">Start Peering</A>
|
||||
<A href="" class="btn btn-outline">Support Us</A>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="container mx-auto p-4">
|
||||
<div class="flex flex-col md:flex-row mx-8 justify-center min-h-[40vh]">
|
||||
<div class="grow p-8">
|
||||
<div class="flex items-center sticky top-[40vh] text-5xl relative">
|
||||
<h2>Internet Exchange</h2>
|
||||
<div class="circle bg-primary h-5 w-5 rounded-full absolute left-[-2.5rem] md:left-auto md:right-[-2.75rem]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow flex flex-col justify-center gap-4 p-8 border-primary" style="border-bottom-width: 0.25rem; border-left-width: 0.25rem;">
|
||||
<p class="text-xl">DD-IX is an Internet exchange for Dresden and whole Saxony. As a non-commercial platform, we are open to all Internet stakeholders that are interested in multilateral exchange of Internet traffic.</p>
|
||||
<A href="" class="btn btn-outline w-fit">Learn More</A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col-reverse md:flex-row mx-8 mt-[-0.25rem] justify-center min-h-[40vh]">
|
||||
<div class="grow flex flex-col justify-center gap-4 p-8 border-primary" style="border-bottom-width: 0.25rem; border-right-width: 0.25rem">
|
||||
<p class="text-xl">The DD-IX is operated by committed people of the DD-IX Dresden Internet Exchange e.V. The DD-IX Dresden Internet Exchange e.V. is a registered association under German law. Our mission is the economical, ecological, and robust exchange of data over the Internet. To enable direct data delivery between source and destination, we leverage the unique advantages of an Internet Exchage Point (IXP).</p>
|
||||
<A href="" class="btn btn-outline w-fit">Support Us</A>
|
||||
</div>
|
||||
<div class="grow p-8 border-transparent md:border-base-100" style="border-top-width: 0.25rem;">
|
||||
<div class="flex items-center sticky top-[40vh] text-5xl relative">
|
||||
<div class="circle bg-primary h-5 w-5 rounded-full absolute right-[-2.5rem] md:right-auto md:left-[-2.75rem]"></div>
|
||||
<h2>Association</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col md:flex-row mx-8 mt-[-0.25rem] justify-center min-h-[40vh]">
|
||||
<div class="grow p-8 border-transparent md:border-base-100" style="border-top-width: 0.25rem">
|
||||
<div class="flex items-center sticky top-[40vh] text-5xl relative">
|
||||
<h2>Support</h2>
|
||||
<div class="circle bg-primary h-5 w-5 rounded-full absolute left-[-2.5rem] md:left-auto md:right-[-2.75rem]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow flex flex-col justify-center gap-4 p-8 border-primary" style="border-bottom-width: 0.25rem; border-left-width: 0.25rem;">
|
||||
<p class="text-xl">Join us for an exciting journey. As peer, sponsor, or member of the association you will be part of the development of the DD-IX - the catalyst for the digital future in Saxony!</p>
|
||||
<A href="" class="btn btn-outline w-fit">Support Us</A>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="mt-40 mb-16 text-5xl">News</h2>
|
||||
<NewsList limit={3} />
|
||||
<A href="/news" class="btn btn-primary mt-4">View More</A>
|
||||
</section>
|
||||
|
||||
</main>
|
48
src/routes/network.mdx
Normal file
48
src/routes/network.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
<section class="container mx-auto p-4">
|
||||
|
||||
<h1 class="mb-12 mt-40">Network</h1>
|
||||
|
||||
Currently there are 3 participants. Have a look at the list below for more information.
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Member</th>
|
||||
<th>Name</th>
|
||||
<th>ASN</th>
|
||||
<th>Connections</th>
|
||||
<th>RSv4</th>
|
||||
<th>RSv6</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>1</th>
|
||||
<td>no</td>
|
||||
<td>AS112 Reverse DNS</td>
|
||||
<td>112</td>
|
||||
<td>1Gbit</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2</th>
|
||||
<td>yes</td>
|
||||
<td>hair of Distributed and Networked Systems at TUD</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3</th>
|
||||
<td>yes</td>
|
||||
<td>IBH IT-Service GmbH</td>
|
||||
<td>15372</td>
|
||||
<td>10Gbit</td>
|
||||
<td>yes</td>
|
||||
<td>yes</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</section>
|
45
src/routes/news/[slug].tsx
Normal file
45
src/routes/news/[slug].tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
import {
|
||||
cache,
|
||||
createAsync,
|
||||
A,
|
||||
type RouteDefinition,
|
||||
useParams,
|
||||
} from "@solidjs/router";
|
||||
|
||||
const getPost = cache(async (slug) => {
|
||||
"use server";
|
||||
return await fetch(`https://content.dd-ix.net/news/en/${slug}`).then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "news-post");
|
||||
|
||||
export const route = {
|
||||
load: ({ params }) => {
|
||||
getPost(params.slug);
|
||||
},
|
||||
} satisfies RouteDefinition;
|
||||
|
||||
export default () => {
|
||||
const params = useParams();
|
||||
const post = createAsync(() => getPost(params.slug));
|
||||
|
||||
return (
|
||||
<main>
|
||||
<div class="relative">
|
||||
<img
|
||||
src={`https://content.dd-ix.net/news/assets/${post()?.image}`}
|
||||
alt={post()?.title}
|
||||
class="min-h-[30vh] max-h-[70vh] w-full object-cover"
|
||||
/>
|
||||
{/* <h1 class="absolute bottom-0 left-0 p-4 backdrop-blur text-white drop-shadow-md bg-gray-800/40">{post()?.title}</h1> */}
|
||||
</div>
|
||||
<section class="container mx-auto p-4">
|
||||
<h1 class="my-12">{post()?.title}</h1>
|
||||
<p>{post()?.published}</p>
|
||||
<p>{post()?.authors.join(", ")}</p>
|
||||
<div innerHTML={post()?.body} />
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
};
|
59
src/routes/news/index.tsx
Normal file
59
src/routes/news/index.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
import { cache, createAsync, A, type RouteDefinition } from "@solidjs/router";
|
||||
|
||||
const getNewsList = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/news/en").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "news-list");
|
||||
|
||||
const getNewsTags = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/news/keywords").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "news-tags");
|
||||
|
||||
export const route = {
|
||||
load: () => {
|
||||
getNewsList();
|
||||
getNewsTags();
|
||||
},
|
||||
} satisfies RouteDefinition;
|
||||
|
||||
export default () => {
|
||||
const newsList = createAsync(() => getNewsList());
|
||||
const tags = createAsync(() => getNewsTags());
|
||||
|
||||
return (
|
||||
<main class="container mx-auto p-4">
|
||||
<h1 class="mb-12 mt-40">News</h1>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<For each={tags()}>
|
||||
{(tag) => (
|
||||
<button class="btn btn-sm">{tag}</button>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<For each={newsList()}>
|
||||
{(post) => (
|
||||
<A href={`/news/${post.slug}`}>
|
||||
<figure class="card md:card-side bg-base-100 shadow-xl mt-4">
|
||||
<img
|
||||
src={`https://content.dd-ix.net/news/assets/${post.image}`}
|
||||
alt={post.title}
|
||||
class="md:w-48 object-cover"
|
||||
/>
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{post.title}</h2>
|
||||
<p>{post.published}</p>
|
||||
<p>{post.description}</p>
|
||||
</div>
|
||||
</figure>
|
||||
</A>
|
||||
)}
|
||||
</For>
|
||||
</main>
|
||||
);
|
||||
};
|
18
src/routes/peering.mdx
Normal file
18
src/routes/peering.mdx
Normal file
@ -0,0 +1,18 @@
|
||||
<section class="container mx-auto p-4">
|
||||
|
||||
<h1 class="mb-12 mt-40">Peering</h1>
|
||||
|
||||
## What is peering?
|
||||
Peering is a term from network technology. It enables ISPs (Internet Service Providers) or network operators to easily exchange data with each other. This data transfer between peering partners is free of charge and offers numerous advantages.
|
||||
|
||||
## Why should I peer?
|
||||
The aim of peering is to route traffic between the participating networks more efficiently and to avoid bottlenecks. Through peering connections provided by DD-IX, we enable all participants to route network packets among each other shorter and faster.
|
||||
|
||||
Optimal network packet forwarding is an important aspect of building a robust and efficient Internet. Peering with an IXP allows access to content and services provided by other network operators or ISPs without the need to establish many direct peerings among each other.
|
||||
|
||||
---
|
||||
An IXP also enables better resilience, as traffic can be transmitted even if a link to a particular network fails, as long as there are routes through alternative peering partners.
|
||||
|
||||
Peering through an IXP like the DD-IX reduces the need for expensive Internet transit services. Because only the connection are paid for and not the data volume used.
|
||||
|
||||
</section>
|
146
src/routes/statistics.tsx
Normal file
146
src/routes/statistics.tsx
Normal file
@ -0,0 +1,146 @@
|
||||
import { createSignal, For, Show } from "solid-js";
|
||||
import { cache, createAsync, A, type RouteDefinition } from "@solidjs/router";
|
||||
import { clientOnly } from "@solidjs/start";
|
||||
const TrafficChart = clientOnly(() => import("~/components/TrafficChart"));
|
||||
const DNSChart = clientOnly(() => import("~/components/DNSChart"));
|
||||
|
||||
const getTraffic = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/stats/traffic").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "stats-traffic");
|
||||
|
||||
const getQueries = cache(async () => {
|
||||
"use server";
|
||||
return await fetch("https://content.dd-ix.net/stats/as112").then((data) =>
|
||||
data.json()
|
||||
);
|
||||
}, "stats-queries");
|
||||
|
||||
export const route = {
|
||||
load: () => {
|
||||
getTraffic();
|
||||
getQueries();
|
||||
},
|
||||
} satisfies RouteDefinition;
|
||||
|
||||
export default () => {
|
||||
const traffic = createAsync(() => getTraffic());
|
||||
const queries = createAsync(() => getQueries());
|
||||
|
||||
return (
|
||||
<section class="container mx-auto p-4">
|
||||
<h1 class="mb-12 mt-40">Statistics</h1>
|
||||
<h2>Traffic</h2>
|
||||
<div role="tablist" class="tabs tabs-lifted">
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_2"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Two days"
|
||||
checked
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<TrafficChart
|
||||
data={traffic()?.two_days}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_2"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Week"
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<TrafficChart
|
||||
data={traffic()?.seven_days}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_2"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Month"
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<TrafficChart
|
||||
data={traffic()?.month}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>DNS Queries</h2>
|
||||
<div role="tablist" class="tabs tabs-lifted">
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_3"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Two days"
|
||||
checked
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<DNSChart
|
||||
data={queries()?.two_days}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_3"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Week"
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<DNSChart
|
||||
data={queries()?.seven_days}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
name="my_tabs_3"
|
||||
role="tab"
|
||||
class="tab"
|
||||
aria-label="Month"
|
||||
/>
|
||||
<div
|
||||
role="tabpanel"
|
||||
class="tab-content bg-base-100 border-base-300 rounded-box p-6"
|
||||
>
|
||||
<DNSChart
|
||||
data={queries()?.month}
|
||||
fallback={<div>Loading</div>}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
33
tailwind.config.cjs
Normal file
33
tailwind.config.cjs
Normal file
@ -0,0 +1,33 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{html,js,jsx,ts,tsx,mdx,md}"],
|
||||
plugins: [require("daisyui")],
|
||||
theme: {
|
||||
fontFamily: {
|
||||
sans: ["Ubuntu", "sans-serif"],
|
||||
},
|
||||
},
|
||||
daisyui: {
|
||||
themes: [
|
||||
{
|
||||
light: {
|
||||
...require("daisyui/src/theming/themes")["corporate"],
|
||||
primary: "#209680",
|
||||
"primary-focus": "#6ce0ca",
|
||||
secondary: "#ccff00",
|
||||
"secondary-focus": "#88b100",
|
||||
},
|
||||
},
|
||||
{
|
||||
dark: {
|
||||
...require("daisyui/src/theming/themes")["business"],
|
||||
primary: "#209680",
|
||||
"primary-focus": "#6ce0ca",
|
||||
secondary: "#ccff00",
|
||||
"secondary-focus": "#88b100",
|
||||
},
|
||||
},
|
||||
],
|
||||
darkTheme: "dark",
|
||||
},
|
||||
};
|
19
tsconfig.json
Normal file
19
tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"types": ["vinxi/types/client"],
|
||||
"isolatedModules": true,
|
||||
"paths": {
|
||||
"~/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user