diff --git a/api/Dockerfile b/api/Dockerfile index bcb112a..4a29454 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -6,12 +6,13 @@ COPY *.go ./ COPY *.mod ./ COPY *.sum ./ COPY Makefile ./ +COPY config ./config +COPY database ./database +COPY routes ./routes +COPY sql ./sql +COPY status ./status COPY util ./util COPY views ./views -COPY routes ./routes -COPY config ./config -COPY status ./status -COPY database ./database EXPOSE 7001 RUN make diff --git a/api/Makefile b/api/Makefile index e115a02..062716b 100644 --- a/api/Makefile +++ b/api/Makefile @@ -6,7 +6,7 @@ api.elf: $(GOSRCS) go build -o $@ run: - API_DEBUG=true API_APP_URL=http://localhost:5173/ API_PASSWORD=test ./api.elf + API_DEBUG=true API_APP_URL=http://localhost:7002 API_PASSWORD=test ./api.elf format: gofmt -s -w . diff --git a/api/routes/metrics.go b/api/routes/metrics.go index e7fb3ab..fc91c48 100644 --- a/api/routes/metrics.go +++ b/api/routes/metrics.go @@ -66,7 +66,7 @@ func GET_Metrics(c *fiber.Ctx) error { if result["since"] == 0 { result["since"] = uint64(time.Now().Truncate(24 * time.Hour).Unix()) - if err = db.MetricsSet("since", result["since"]); err != nil { + if err = db.MetricsSet("start_date", result["since"]); err != nil { return util.ErrInternal(c, err) } } diff --git a/app/Dockerfile b/app/Dockerfile index f757326..524db3a 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -16,8 +16,7 @@ COPY --from=build /app/build ./build COPY --from=build /app/package.json ./package.json COPY --from=build /app/package-lock.json ./package-lock.json -EXPOSE 4173 - +EXPOSE 7001 RUN bun install CMD ["bun", "build/index.js"] diff --git a/app/package-lock.json b/app/package-lock.json index e9f213f..d8ac382 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,6 +9,7 @@ "version": "6.0", "dependencies": { "@types/dompurify": "^3.2.0", + "marked": "^15.0.6", "svelte-i18n": "^4.0.1" }, "devDependencies": { @@ -1396,6 +1397,18 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/marked": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.6.tgz", + "integrity": "sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/memoizee": { "version": "0.4.17", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", diff --git a/app/package.json b/app/package.json index 1d47b98..d1f763a 100644 --- a/app/package.json +++ b/app/package.json @@ -22,6 +22,7 @@ "type": "module", "dependencies": { "@types/dompurify": "^3.2.0", + "marked": "^15.0.6", "svelte-i18n": "^4.0.1" } } diff --git a/app/src/lib/api.js b/app/src/lib/api.js index 2e24f92..99bbb0e 100644 --- a/app/src/lib/api.js +++ b/app/src/lib/api.js @@ -1,13 +1,13 @@ import { urljoin } from "$lib/util.js"; -const version = "v1"; -const url = urljoin(import.meta.env.APP_API_URL, version); +const api_version = "v1"; +const api_url = urljoin(import.meta.env.APP_API_URL, api_version); -function api_url(path = null, query = {}) { - return urljoin(url, path, query); +function api_urljoin(path = null, query = {}) { + return urljoin(api_url, path, query); } -function check_err(json) { +function api_check_err(json) { if (!("error" in json)) throw new Error('API response is missing the "error" key'); if (json["error"] != "") throw new Error(`API returned an error: ${json["error"]}`); @@ -15,23 +15,23 @@ function check_err(json) { if (!("result" in json)) throw new Error('API response is missing the "result" key'); } -async function GET(fetch, url) { +async function api_http_get(fetch, url) { const res = await fetch(url); const json = await res.json(); - check_err(json); + api_check_err(json); return json["result"]; } -async function get_metrics(fetch) { - return GET(fetch, api_url("/metrics")); +async function api_get_metrics(fetch) { + return await api_http_get(fetch, api_urljoin("/metrics")); } -async function get_services(fetch) { - return GET(fetch, api_url("/services")); +async function api_get_services(fetch) { + return await api_http_get(fetch, api_urljoin("/services")); } -async function get_projects(fetch) { - return GET(fetch, api_url("/projects")); +async function api_get_projects(fetch) { + return await api_http_get(fetch, api_urljoin("/projects")); } -export { version, api_url, get_metrics, get_services, get_projects }; +export { api_version, api_urljoin, api_get_metrics, api_get_services, api_get_projects }; diff --git a/app/src/lib/doc.js b/app/src/lib/doc.js new file mode 100644 index 0000000..e1a29ca --- /dev/null +++ b/app/src/lib/doc.js @@ -0,0 +1,28 @@ +import { urljoin } from "$lib/util.js"; + +function doc_urljoin(path = null, query = {}) { + return urljoin(import.meta.env.APP_DOC_URL, path, query); +} + +function doc_check_err(json) { + if ("error" in json) throw new Error(`Documentation server returned an error: ${json["error"]}`); +} + +async function doc_http_get(fetch, url) { + const res = await fetch(url); + const json = await res.json(); + doc_check_err(json); + return json; +} + +async function doc_get_list(fetch) { + return (await doc_http_get(fetch, doc_urljoin("/list")))["list"]; +} + +async function doc_get(fetch, name) { + let url = doc_urljoin("/get"); + url = urljoin(url, name); + return await doc_http_get(fetch, url); +} + +export { doc_urljoin, doc_get, doc_get_list }; diff --git a/app/src/lib/error.svelte b/app/src/lib/error.svelte index 7bea385..1df9488 100644 --- a/app/src/lib/error.svelte +++ b/app/src/lib/error.svelte @@ -34,6 +34,7 @@ display: flex; flex-direction: column; justify-content: end; + align-items: flex-start; gap: 10px; padding: 50px; diff --git a/app/src/lib/footer.svelte b/app/src/lib/footer.svelte index 0655b6b..f4b365d 100644 --- a/app/src/lib/footer.svelte +++ b/app/src/lib/footer.svelte @@ -1,6 +1,6 @@ @@ -21,16 +21,14 @@ / - {$_("footer.license")}{$_("footer.license")} / - {$_("footer.privacy")}{$_("footer.privacy")} diff --git a/app/src/lib/head.svelte b/app/src/lib/head.svelte index 53bdc0e..0fa0627 100644 --- a/app/src/lib/head.svelte +++ b/app/src/lib/head.svelte @@ -1,6 +1,6 @@ @@ -13,5 +13,10 @@ - + diff --git a/app/src/lib/header.svelte b/app/src/lib/header.svelte index f90e894..15eadd1 100644 --- a/app/src/lib/header.svelte +++ b/app/src/lib/header.svelte @@ -8,9 +8,7 @@ - - {title.toLowerCase()} - + {title.toLowerCase()} _ diff --git a/app/src/lib/service.svelte b/app/src/lib/service.svelte index 38b6a3e..4c60fdf 100644 --- a/app/src/lib/service.svelte +++ b/app/src/lib/service.svelte @@ -73,11 +73,13 @@ main .info .title h1 { font-size: var(--size-5); margin-bottom: 8px; + font-weight: 900; } main .info .title p { font-size: var(--size-4); color: var(--white-2); + font-weight: 100; } main .info .links { diff --git a/app/src/locales/en.json b/app/src/locales/en.json index 3f54a0a..36e1e39 100644 --- a/app/src/locales/en.json +++ b/app/src/locales/en.json @@ -43,6 +43,7 @@ }, "services": { "title": "Service Status", + "none": "No services found", "search": "Search for a service", "feed": "News and updates", "last": "Last checked at {time}", @@ -63,6 +64,9 @@ "address": "Adress/Link" } }, + "doc": { + "title": "Documentation" + }, "error": { "title": "Something went wrong!", "report": "Report this issue" diff --git a/app/src/locales/tr.json b/app/src/locales/tr.json index 119e393..3d0fedd 100644 --- a/app/src/locales/tr.json +++ b/app/src/locales/tr.json @@ -44,6 +44,7 @@ }, "services": { "title": "Servis Durumu", + "none": "Servis bulunamadı", "search": "Bir servisi ara", "feed": "Yenilikler ve güncellemeler", "last": "Son kontrol zamanı {time}", @@ -64,6 +65,9 @@ "address": "Adres/Bağlantı" } }, + "doc": { + "title": "Dökümantasyon" + }, "error": { "title": "Birşeyler yanlış gitti!", "report": "Bu sorunu raporlayın" diff --git a/app/src/routes/+layout.js b/app/src/routes/+layout.js index 3275217..471e781 100644 --- a/app/src/routes/+layout.js +++ b/app/src/routes/+layout.js @@ -1,5 +1,6 @@ import { default_language, language, set_lang } from "$lib/util.js"; -import { get_services, get_projects } from "$lib/api.js"; +import { api_get_services, api_get_projects } from "$lib/api.js"; +import { doc_get_list } from "$lib/doc.js"; import languages from "$lib/lang.js"; import { init, register, waitLocale } from "svelte-i18n"; @@ -23,8 +24,9 @@ export async function load({ fetch }) { try { return { - services: await get_services(fetch), - projects: await get_projects(fetch), + services: await api_get_services(fetch), + projects: await api_get_projects(fetch), + docs: await doc_get_list(fetch), error: null, }; } catch (err) { diff --git a/app/src/routes/doc/[name]/+page.js b/app/src/routes/doc/[name]/+page.js new file mode 100644 index 0000000..995acae --- /dev/null +++ b/app/src/routes/doc/[name]/+page.js @@ -0,0 +1,11 @@ +import { goto } from "$app/navigation"; +import { doc_get } from "$lib/doc"; + +export async function load({ fetch, params }) { + try { + return await doc_get(fetch, params.name); + } catch (err) { + if (err.toString().includes("not found")) return goto("/"); + return { error: err }; + } +} diff --git a/app/src/routes/doc/[name]/+page.svelte b/app/src/routes/doc/[name]/+page.svelte new file mode 100644 index 0000000..b8e80ab --- /dev/null +++ b/app/src/routes/doc/[name]/+page.svelte @@ -0,0 +1,104 @@ + + + + + + + + {@html marked.parse(data.content)} + + + {#each data.docs as doc} + {#if doc.title == data.title} + + {doc.title} + {doc.desc} + + {:else} + + {doc.title} + {doc.desc} + + {/if} + {/each} + + + + diff --git a/app/src/routes/services/+page.svelte b/app/src/routes/services/+page.svelte index 2b7f94b..3ea73da 100644 --- a/app/src/routes/services/+page.svelte +++ b/app/src/routes/services/+page.svelte @@ -4,8 +4,8 @@ import Link from "$lib/link.svelte"; import Head from "$lib/head.svelte"; + import { api_urljoin } from "$lib/api.js"; import { language } from "$lib/util.js"; - import { api_url } from "$lib/api.js"; import { _ } from "svelte-i18n"; let { data } = $props(); @@ -25,6 +25,14 @@ else if (s.desc[$language].toLowerCase().includes(value)) services.push(s); }); } + + function get_services() { + return services.filter((s) => { + return ( + s.desc[$language] !== "" && s.desc[$language] !== null && s.desc[$language] !== undefined + ); + }); + }