first commit

This commit is contained in:
creations 2025-05-18 19:12:34 -04:00
commit 25e7da24e6
Signed by: creations
GPG key ID: 8F553AA4320FC711
17 changed files with 300 additions and 0 deletions

28
LICENSE Normal file
View file

@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2025, creations.works
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

3
README.md Normal file
View file

@ -0,0 +1,3 @@
## License
[BSD 3](LICENSE)

44
biome.json Normal file
View file

@ -0,0 +1,44 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": true,
"ignore": []
},
"formatter": {
"enabled": true,
"indentStyle": "tab",
"lineEnding": "lf"
},
"organizeImports": {
"enabled": true
},
"css": {
"formatter": {
"indentStyle": "tab",
"lineEnding": "lf"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedImports": "error"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"indentStyle": "tab",
"lineEnding": "lf",
"jsxQuoteStyle": "double",
"semicolons": "always"
}
}
}

36
config/index.ts Normal file
View file

@ -0,0 +1,36 @@
import { logger } from "@creations.works/logger";
import { normalizeFqdn } from "@lib/char";
const environment: Environment = {
port: Number.parseInt(process.env.PORT || "8080", 10),
host: process.env.HOST || "0.0.0.0",
development:
process.env.NODE_ENV === "development" || process.argv.includes("--dev"),
fqdn: normalizeFqdn(process.env.FQDN) || "http://localhost:8080",
};
function verifyRequiredVariables(): void {
const requiredVariables = [
"HOST",
"PORT",
"FQDN",
"BACKEND_URL",
];
let hasError = false;
for (const key of requiredVariables) {
const value = process.env[key];
if (value === undefined || value.trim() === "") {
logger.error(`Missing or empty environment variable: ${key}`);
hasError = true;
}
}
if (hasError) {
process.exit(1);
}
}
export { environment, verifyRequiredVariables };

28
package.json Normal file
View file

@ -0,0 +1,28 @@
{
"name": "atums.world.frontend",
"version": "0.0.0",
"description": "",
"private": true,
"type": "module",
"scripts": {
"start": "bun src/index.ts",
"dev": "bun src/index.ts --dev",
"build": "vite build",
"serve": "vite preview",
"lint": "bunx biome check",
"lint:fix": "bunx biome check --fix",
"cleanup": "rm -rf logs node_modules bun.lock"
},
"license": "BSD-3-Clause",
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@types/bun": "^1.2.13",
"vite": "^6.3.5",
"vite-plugin-solid": "^2.11.6",
"vite-tsconfig-paths": "^5.1.4"
},
"dependencies": {
"@creations.works/logger": "^1.0.3",
"solid-js": "^1.9.5"
}
}

19
src/index.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/assets/favicon.ico" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/views/index.tsx"></script>
</body>
</html>

28
src/index.ts Normal file
View file

@ -0,0 +1,28 @@
import { resolve } from "node:path";
import { environment, verifyRequiredVariables } from "@config";
import { logger } from "@creations.works/logger";
import { createServer } from "vite";
import solidPlugin from "vite-plugin-solid";
import tsconfigPaths from "vite-tsconfig-paths";
verifyRequiredVariables();
const server = await createServer({
root: resolve("src"),
publicDir: resolve("src/public"),
plugins: [solidPlugin(), tsconfigPaths()],
server: {
port: environment.port,
host: environment.host,
strictPort: true,
},
build: {
target: "esnext",
},
});
await server.listen();
logger.info(
`Server is running at http://${environment.host}:${environment.port}`,
);

5
src/lib/char.ts Normal file
View file

@ -0,0 +1,5 @@
export function normalizeFqdn(value?: string): string | null {
if (!value) return null;
if (!/^https?:\/\//.test(value)) return `https://${value}`;
return value;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 155.3"><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" fill="#76b3e1"/><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="27.5" y1="3" x2="152" y2="63.5"><stop offset=".1" stop-color="#76b3e1"/><stop offset=".3" stop-color="#dcf2fd"/><stop offset="1" stop-color="#76b3e1"/></linearGradient><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" opacity=".3" fill="url(#a)"/><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" fill="#518ac8"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="95.8" y1="32.6" x2="74" y2="105.2"><stop offset="0" stop-color="#76b3e1"/><stop offset=".5" stop-color="#4377bb"/><stop offset="1" stop-color="#1f3b77"/></linearGradient><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" opacity=".3" fill="url(#b)"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="18.4" y1="64.2" x2="144.3" y2="149.8"><stop offset="0" stop-color="#315aa9"/><stop offset=".5" stop-color="#518ac8"/><stop offset="1" stop-color="#315aa9"/></linearGradient><path d="M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z" fill="url(#c)"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="75.2" y1="74.5" x2="24.4" y2="260.8"><stop offset="0" stop-color="#4377bb"/><stop offset=".5" stop-color="#1a336b"/><stop offset="1" stop-color="#1a336b"/></linearGradient><path d="M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z" fill="url(#d)"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

14
src/views/App.tsx Normal file
View file

@ -0,0 +1,14 @@
import type { Component } from "solid-js";
import styles from "@views/css/App.module.css";
const App: Component = () => {
return (
<div class={styles.App}>
<header class={styles.header}>
</header>
</div>
);
};
export default App;

View file

@ -0,0 +1,33 @@
.App {
text-align: center;
}
.logo {
animation: logo-spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
}
.header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.link {
color: #b318f0;
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

13
src/views/css/index.css Normal file
View file

@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}

13
src/views/index.tsx Normal file
View file

@ -0,0 +1,13 @@
import { render } from "solid-js/web";
import "@views/css/index.css";
import App from "@views/App";
const root = document.getElementById("root");
if (!(root instanceof HTMLElement)) {
throw new Error("Root element not found");
}
render(() => <App />, root);

25
tsconfig.json Normal file
View file

@ -0,0 +1,25 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@views/*": ["src/views/*"],
"@config": ["config/index.ts"],
"@config/*": ["config/*"],
"@types/*": ["types/*"],
"@lib/*": ["src/lib/*"]
},
"typeRoots": ["./src/types", "./node_modules/@types"],
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"noEmit": true,
"isolatedModules": true
},
"include": ["src", "types", "config"]
}

6
types/config.d.ts vendored Normal file
View file

@ -0,0 +1,6 @@
type Environment = {
port: number;
host: string;
development: boolean;
fqdn: string;
};

4
types/css.d.ts vendored Normal file
View file

@ -0,0 +1,4 @@
declare module "*.module.css" {
const classes: { [key: string]: string };
export default classes;
}