This commit is contained in:
Patrick Alvin Alcala 2025-11-20 13:03:40 +08:00
parent 4184942584
commit afb5f3a287
66 changed files with 550 additions and 57 deletions

9
frontend/.editorconfig Normal file
View file

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

28
frontend/.gitignore vendored Normal file
View file

@ -0,0 +1,28 @@
dist
.wrangler
.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

1
frontend/README.md Normal file
View file

@ -0,0 +1 @@
# DASIG

11
frontend/app.config.ts Normal file
View file

@ -0,0 +1,11 @@
import { defineConfig } from '@solidjs/start/config'
export default defineConfig({
ssr: false,
server: {
static: true,
prerender: {
crawlLinks: true,
},
},
})

42
frontend/biome.json Normal file
View file

@ -0,0 +1,42 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.6/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": { "ignoreUnknown": false },
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 320,
"attributePosition": "auto",
"bracketSameLine": false,
"bracketSpacing": true,
"expand": "auto",
"useEditorconfig": true
},
"linter": { "enabled": true, "rules": { "recommended": true } },
"javascript": {
"formatter": {
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "es5",
"semicolons": "asNeeded",
"arrowParentheses": "always",
"bracketSameLine": false,
"quoteStyle": "single",
"attributePosition": "auto",
"bracketSpacing": true
}
},
"html": {
"formatter": {
"indentScriptAndStyle": false,
"selfCloseVoidElements": "always"
}
},
"assist": {
"enabled": true,
"actions": { "source": { "organizeImports": "on" } }
}
}

View file

@ -0,0 +1,3 @@
import { atom } from 'nanostores'
export const $backendUrl = atom('http://localhost:8080')

View file

@ -0,0 +1,20 @@
import { atom } from 'nanostores'
export const $tokenName = atom<string>('dasig') // output: dasig-token
export const $tokenEncryption = atom<'rsa'>('rsa')
export const $tokenExpiration = atom<number>(9) // expires in 9 seconds
export const $rsaPublicKey = atom<string>(`-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9Aw5Zasdanf2biS69qoQ
/YZbyIM+LS7LOLNN3ot6nZH1FiTqTNy61ffUA2Y/s3hGz9L0+k6gRu7uGBza6XPU
+iuGdXxZd2mc3lrnPfR6SSllMwGlAVkYpQhmkB19igd8aLUbFiJ3pPKkNocv/yQa
ERQ2tXtSxAoEQ9hg4wPgXkuW5PF+yEk9/+eN6tB36lHu9Im44GG18xKkU+VcdsXc
DJVgEpcr1FtJL6uLI+VXc4peZmOdsBN7/MS3Rjb2Ib9TrOADE5qodSc+T8D6GoGH
MOWQGKY6dmfo9cnY3tJ23FfKy9jFOIIrTIdz2ncRaOfxX1oIiTVy4pGG+GxZn5aQ
z+IW8hmSj/oOcrGKr6T6lmKxxxYqBWgvQWef0O0anGfa2y5CTpqdPQ8KEoF2zxPD
EnvcIQiCUmXwML4x18XItY/d60nEn/pxn7a9J9hb3Lxjy94ZXuOgHvqL3XRC9xg+
HvEuAHzUBr+GJM9w4/LF1mQSsmblB8q5S7qNaminYAw6wm35lRy7ZlIbJQlj/EyL
lCKWBbUEHkjzRFCoun9VVUc0guQTsTbchPD7Rgzg3SBK3Gws39n12WQPc7jKto0H
N39sJnNzllXw41gKRy9b2uYuaVYaQ0sjrFJ8ITuyO9NDDaEdeBqBBTtbRp2i0O4K
tvT2kItEEnVzjNutUatVOWcCAwEAAQ==
-----END PUBLIC KEY-----`)

View file

@ -0,0 +1,8 @@
import { atom } from 'nanostores'
export const $websiteName = atom<string>('Dasig Solid')
export const $websiteDescription = atom<string>('A template for next level speed (Solid Version)')
export const $font = atom<string>('inter')
export const $yourName = atom<string>('Pat Alcala')
export const $copyRightYear = atom<number>(2025)

32
frontend/package.json Normal file
View file

@ -0,0 +1,32 @@
{
"name": "dasig-solid",
"type": "module",
"scripts": {
"dev": "vinxi dev",
"build": "vinxi build",
"start": "vinxi start",
"version": "vinxi version"
},
"dependencies": {
"@dotenvx/dotenvx": "^1.51.1",
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.15.0",
"@solidjs/start": "^1.1.0",
"dayjs": "^1.11.19",
"dotenv": "^17.2.3",
"eciesjs": "^0.4.16",
"jsencrypt": "^3.5.4",
"nanostores": "^1.1.0",
"ofetch": "^1.5.1",
"solid-icons": "^1.1.0",
"solid-js": "^1.9.5",
"vinxi": "^0.5.7"
},
"engines": {
"node": ">=22"
},
"devDependencies": {
"@types/node": "^24.7.2",
"sass-embedded": "^1.93.2"
}
}

5466
frontend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load diff

BIN
frontend/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

View file

@ -0,0 +1,23 @@
import { ofetch } from 'ofetch'
import { $backendUrl } from '../../../../configs/config.api'
const URL = $backendUrl.get()
export default async (api: string, value?: any, value2?: any) => {
try {
let fetch
if (!value2) {
if (!value) {
fetch = await ofetch(URL + api, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
} else {
fetch = await ofetch(URL + `${api}/${value}/fetch-data`, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
}
} else {
fetch = await ofetch(URL + `${api}/${value}/${value2}/fetch-data`, { parseResponse: JSON.parse, retry: 3, retryDelay: 500, retryStatusCodes: [400, 404, 405, 500, 502] })
}
const result = fetch
return [result, null]
} catch (error) {
return [[], error]
}
}

View file

@ -0,0 +1,35 @@
import { ofetch } from 'ofetch'
import { $backendUrl } from '../../../../configs/config.api'
import { $tokenName, $tokenExpiration } from '../../../../configs/config.security'
import dayjs from 'dayjs'
import encryptRsa from '../../scripts/functions/encryptRsa'
const URL = $backendUrl.get()
const TOKEN_NAME = $tokenName.get()
const TOKEN_EXPIRATION = $tokenExpiration.get()
export default async (api: string, body: Object) => {
const today = new Date()
const todayUnix = dayjs(today).unix()
const expiration = todayUnix + TOKEN_EXPIRATION
const aes = await encryptRsa(`${api.toString()}-${todayUnix.toString()}-${expiration.toString()}`)
const hash = `${TOKEN_NAME}=${aes}token`
try {
await ofetch(URL + api, {
headers: {
Accept: 'application/json',
'Cache-Control': 'no-cache',
'Dasig-Token': hash,
},
retry: 3,
retryDelay: 500,
retryStatusCodes: [400, 404, 405, 500, 502],
method: 'POST',
body: body,
})
return true
} catch {
return false
}
}

View file

@ -0,0 +1,2 @@
export { default as getApi } from './functions/getApi'
export { default as postApi } from './functions/postApi'

View file

@ -0,0 +1,50 @@
// import '../styles/Background.sass'
// import { Show, createSignal } from 'solid-js'
// import fs from 'fs'
// import webpPath from '../images/background.webp'
// import avifPath from '../images/background.avif'
// import noBackground from '../images/no-background.webp'
// interface Props {
// image?: boolean
// color?: string
// }
// let [imageLoaded, setImageLoaded] = createSignal(false)
// const checkBackground = () => {
// if (!fs.existsSync(avifPath.src) && !fs.existsSync(webpPath.src)) {
// setImageLoaded(true)
// } else {
// setImageLoaded(false)
// }
// }
// export default (props: Props) => {
// checkBackground()
// return (
// <>
// <Show when={props.image}>
// <Show when={imageLoaded()}>
// <picture class="fullscreen">
// <source srcset={avifPath.src} type="image/avif" />
// <source srcset={webpPath.src} type="image/webp" />
// <source srcset={noBackground.src} type="image/webp" />
// <img width="1920" height="auto" decoding="async" loading="lazy" alt="An image background" />
// </picture>
// </Show>
// <Show when={!imageLoaded()}>
// <picture class="fullscreen">
// <source srcset={noBackground.src} type="image/webp" />
// <img width="1920" height="auto" decoding="async" loading="lazy" alt="An alternative background if found no image background" />
// </picture>
// </Show>
// </Show>
// <Show when={!props.image}>
// <div style={{ background: props.color }} class="fullscreen" />
// </Show>
// </>
// )
// }

View file

@ -0,0 +1,19 @@
import '../styles/Box.sass'
import { type JSXElement, createMemo } from 'solid-js'
interface Props {
thickness: number
color?: string
children: JSXElement
curved?: boolean
}
export default (props: Props) => {
const boxClass = createMemo(() => (props.curved ? 'curvedbox' : 'box'))
return (
<section class={boxClass()} style={{ border: `${props.thickness}px solid ${props.color || 'white'}` }}>
{props.children}
</section>
)
}

View file

@ -0,0 +1,83 @@
import '../styles/Button.sass'
import { Show, Switch, Match } from 'solid-js'
interface Props {
label?: string
to?: string
onClick?: () => void
edges?: 'curved' | 'rounded' | 'flat'
design?: 'bu-primary' | 'bu-link' | 'bu-info' | 'bu-success' | 'bu-warning' | 'bu-danger' | 'bu-dark' | 'bu-light' | 'bu-text' | 'bu-ghost' | 'bo-primary' | 'bo-secondary' | 'bo-success' | 'bo-danger' | 'bo-warning' | 'bo-info' | 'bo-light' | 'bo-dark' | 'bo-link'
submit?: boolean
newtab?: boolean
}
const getBorderRadius = (edge: Props['edges']) => {
switch (edge) {
case 'curved':
return 'border-radius: 6px'
case 'rounded':
return 'border-radius: 32px'
case 'flat':
return 'border-radius: 0'
default:
return 'border-radius: 0'
}
}
export default (props: Props) => {
const borderRadius = getBorderRadius(props.edges)
return (
<>
<Show when={props.to}>
<Switch>
<Match when={props.design}>
<a href={props.to} aria-label={props.label} rel="noopener" target={props.newtab ? '_blank' : '_self'} data-astro-prefetch>
<button class={props.design} style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</a>
</Match>
<Match when={!props.design}>
<a href={props.to} aria-label={props.label} rel="noopener" target={props.newtab ? '_blank' : '_self'} data-astro-prefetch>
<button class="button" style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</a>
</Match>
</Switch>
</Show>
<Show when={!props.to}>
<Switch>
<Match when={props.design}>
<Show when={props.submit}>
<button class={props.design} type="submit" style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</Show>
<Show when={!props.submit}>
<button class={props.design} onClick={props.onClick} style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</Show>
</Match>
<Match when={!props.design}>
<Show when={props.submit}>
<button class="button" type="submit" style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</Show>
<Show when={!props.submit}>
<button class="button" onClick={props.onClick} style={borderRadius}>
{props.label || 'Click Me!'}
</button>
</Show>
</Match>
</Switch>
</Show>
</>
)
}

View file

@ -0,0 +1,18 @@
import '../styles/Column.sass'
import type { JSXElement } from 'solid-js'
interface Props {
children: JSXElement
content?: 'top' | 'center' | 'right' | 'split' | 'spaced'
gap?: number
}
export default (props: Props) => {
return (
<>
<section class={`column-${props.content || 'center'}`} style={`gap: ${props.gap}rem`}>
{props.children}
</section>
</>
)
}

View file

@ -0,0 +1,52 @@
import '../styles/HTML.sass'
import { type JSXElement, Show } from 'solid-js'
import background1 from '../images/background.avif'
import background2 from '../images/background.webp'
interface Props {
name: string
description: string
children: JSXElement
font?: 'roboto' | 'inter' | 'montserrat' | 'open-sans' | 'public-sans' | string
preloadBackground?: boolean
author: string
assets: JSXElement
scripts: JSXElement
}
export default (props: Props) => {
return (
<>
<html lang="en">
<head>
<base href="/" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="name" content={props.name} />
<meta name="description" content={props.description} />
<meta name="title" property="og:title" content={props.name} />
<meta name="keywords" content="HTML, CSS, JavaScript" />
<meta name="developer" content={props.author} />
<meta property="og:description" content={props.description} />
<meta property="og:type" content="website" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<Show when={props.font}>
<link rel="preconnect" href="https://cdn.jsdelivr.net" />
</Show>
<Show when={props.preloadBackground}>
<link rel="preload" href={background1} as="image" type="image/svg+xml" />
<link rel="preload" href={background2} as="image" type="image/svg+xml" />
</Show>
{props.assets}
</head>
<body>
<div class={props.font} id="app">
{props.children}
</div>
{props.scripts}
</body>
</html>
</>
)
}

View file

@ -0,0 +1,22 @@
import '../styles/Page.sass'
import { Show } from 'solid-js'
import { Title } from '@solidjs/meta'
interface Props {
children?: any
alignment?: 'row' | 'column'
title: string
}
export default (props: Props) => {
return (
<>
<Show when={props.alignment}>
<main class={props.alignment}><Title>{props.title}</Title>{props.children}</main>
</Show>
<Show when={!props.alignment}>
<main class="page"><Title>{props.title}</Title>{props.children}</main>
</Show>
</>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,3 @@
export { default as HTML } from './components/HTML'
export { default as Page } from './components/Page'
export { default as Column } from './components/Column'

View file

@ -0,0 +1,13 @@
import { JSEncrypt } from 'jsencrypt'
import { $rsaPublicKey } from '../../../../configs/config.security'
const enc = new JSEncrypt()
const PUBLIC_KEY = $rsaPublicKey.get()
export default async (message: string) => {
enc.setPublicKey(PUBLIC_KEY)
const encrypted = enc.encrypt(message).toString()
const fixedEncrypted = encrypted.replace(/\//g, '~')
return fixedEncrypted
}

View file

@ -0,0 +1 @@
export { default as encryptRsa } from './functions/encryptRsa'

View file

@ -0,0 +1 @@
@use '/src/styles/classes.sass'

View file

@ -0,0 +1,6 @@
.box
padding: 1rem
.curvedbox
@extend .box
border-radius: 8px

View file

@ -0,0 +1,223 @@
@use '/src/styles/variables.sass' as vars
@use '/src/styles/fonts.sass' as fonts
@use 'sass:color'
$bulmaPrimary: rgb(0, 235, 199)
$bulmaPrimaryText: rgb(0, 31, 26)
$bulmaLink: rgb(92, 111, 255)
$bulmaLinkText: rgb(245, 246, 255)
$bulmaInfo: rgb(128, 217, 255)
$bulmaInfoText: rgb(0, 36, 51)
$bulmaSuccess: rgb(91, 205, 154)
$bulmaSuccessText: rgb(10, 31, 21)
$bulmaWarning: rgb(255, 191, 41)
$bulmaWarningText: rgb(41, 29, 0)
$bulmaDanger: rgb(255, 128, 153)
$bulmaDangerText: rgb(26, 0, 5)
$bulmaLight: rgb(255, 255, 255)
$bulmaLightText: rgb(46, 51, 61)
$bulmaDark: rgb(57, 63, 76)
$bulmaDarkText: rgb(243, 244, 246)
$bulmaText: rgb(31, 34, 41)
$bulmaTextText: rgb(235, 236, 240)
$bulmaGhost: rgba(0,0,0,0)
$bulmaGhostText: rgb(66, 88, 255)
$bootstrapTextLight: rgb(255, 255, 253)
$bootstrapTextDark: rgb(0, 0, 2)
$bootstrapTextLink: rgb(139, 185, 254)
$bootstrapPrimary: rgb(13, 110, 253)
$bootstrapSecondary: rgb(92, 99, 106)
$bootstrapSuccess: rgb(21, 115, 71)
$bootstrapDanger: rgb(187, 45, 59)
$bootstrapWarning: rgb(255, 202, 44)
$bootstrapInfo: rgb(49, 210, 242)
$bootstrapLight: rgb(211, 212, 213)
$bootstrapDark: rgb(33, 37, 41)
.button
background-color: vars.$primaryColor
border: none
color: white
padding: 0.5rem 1.25rem
text-align: center
text-decoration: none
display: inline-block
font-size: 1rem
font-weight: 500
cursor: pointer
transition: all 0.2s ease-out
&:hover
background-color: color.adjust(vars.$primaryColor, $blackness: 20%)
&:active
transform: scale(0.95)
.bu-primary
@extend .button
font-family: fonts.$Inter
background-color: $bulmaPrimary
color: $bulmaPrimaryText
border: none
font-size: 1rem
border-radius: 0.375rem
font-weight: 500
padding: 0.5rem 1.25rem
height: 2.5rem
&:hover
background-color: color.adjust($bulmaPrimary, $lightness: 10%)
.bu-link
@extend .bu-primary
background-color: $bulmaLink
color: $bulmaLinkText
&:hover
background-color: color.adjust($bulmaLink, $lightness: 5%)
.bu-info
@extend .bu-primary
background-color: $bulmaInfo
color: $bulmaInfoText
&:hover
background-color: color.adjust($bulmaInfo, $lightness: 5%)
.bu-success
@extend .bu-primary
background-color: $bulmaSuccess
color: $bulmaSuccessText
&:hover
background-color: color.adjust($bulmaSuccess, $lightness: 5%)
.bu-warning
@extend .bu-primary
background-color: $bulmaWarning
color: $bulmaWarningText
&:hover
background-color: color.adjust($bulmaWarning, $lightness: 5%)
.bu-danger
@extend .bu-primary
background-color: $bulmaDanger
color: $bulmaDangerText
&:hover
background-color: color.adjust($bulmaDanger, $lightness: 5%)
.bu-light
@extend .bu-primary
background-color: $bulmaLight
color: $bulmaLightText
&:hover
background-color: color.adjust($bulmaLight, $lightness: 5%)
.bu-dark
@extend .bu-primary
background-color: $bulmaDark
color: $bulmaDarkText
&:hover
background-color: color.adjust($bulmaDark, $lightness: 5%)
.bu-text
@extend .bu-primary
background-color: rgba(0,0,0,0)
color: $bulmaTextText
text-decoration: underline
&:hover
background-color: hsl(221,14%,14%)
.bu-ghost
@extend .bu-primary
background-color: $bulmaGhost
color: $bulmaGhostText
&:hover
background-color: transparent
text-decoration: underline
.bo-primary
@extend .button
font-family: 'Segoe UI', fonts.$Roboto
background-color: $bootstrapPrimary
color: $bootstrapTextLight
border: none
font-size: 1rem
border-radius: 0.375rem
font-weight: 400
padding: 0.5rem 1.25rem
height: 2.5rem
margin: 0.25rem 0.125rem
&:hover
background-color: color.adjust($bootstrapPrimary, $blackness: 10%)
.bo-secondary
@extend .bo-primary
background-color: $bootstrapSecondary
&:hover
background-color: color.adjust($bootstrapSecondary, $blackness: 10%)
.bo-success
@extend .bo-primary
background-color: $bootstrapSuccess
&:hover
background-color: color.adjust($bootstrapSuccess, $blackness: 10%)
.bo-danger
@extend .bo-primary
background-color: $bootstrapDanger
&:hover
background-color: color.adjust($bootstrapDanger, $blackness: 10%)
.bo-warning
@extend .bo-primary
background-color: $bootstrapWarning
color: $bootstrapTextDark
&:hover
background-color: color.adjust($bootstrapWarning, $lightness: 5%)
.bo-info
@extend .bo-primary
background-color: $bootstrapInfo
color: $bootstrapTextDark
&:hover
background-color: color.adjust($bootstrapInfo, $lightness: 5%)
.bo-light
@extend .bo-primary
background-color: $bootstrapLight
color: $bootstrapTextDark
&:hover
background-color: color.adjust($bootstrapLight, $blackness: 10%)
.bo-dark
@extend .bo-primary
background-color: $bootstrapDark
// color: $bootstrapTextDark
&:hover
background-color: color.adjust($bootstrapDark, $lightness: 10%)
.bo-link
@extend .bo-primary
background-color: transparent
color: $bootstrapTextLink
text-decoration: underline
&:hover
color: color.adjust($bootstrapTextLink, $lightness: 5%)
background-color: transparent

View file

@ -0,0 +1,39 @@
.column-top
display: flex
flex-direction: column
flex-wrap: wrap
justify-content: flex-start
align-items: center
align-content: center
.column-center
display: flex
flex-direction: column
flex-wrap: wrap
justify-content: center
align-items: center
align-content: center
.column-right
display: flex
flex-direction: column
flex-wrap: wrap
justify-content: flex-end
align-items: center
align-content: center
.column-split
display: flex
flex-direction: column
flex-wrap: wrap
justify-content: space-between
align-items: center
align-content: center
.column-spaced
display: flex
flex-direction: column
flex-wrap: wrap
justify-content: space-around
align-items: center
align-content: center

View file

@ -0,0 +1,13 @@
@use '/src/styles/breakpoint.sass' as view
.footer
padding: 1rem 0
margin: 0 2rem
position: fixed
bottom: 0
width: 100%
opacity: 0.8
font-size: 1rem
@media only screen and (max-width: view.$tablet)
font-size: 0.75rem

View file

View file

@ -0,0 +1,25 @@
@use '/src/styles/variables.sass' as vars
@use '/src/styles/fonts.sass' as fonts
.body
color: vars.$textColor
.inter
@extend .body
font-family: fonts.$Inter
.roboto
@extend .body
font-family: fonts.$Roboto
.montserrat
@extend .body
font-family: fonts.$Montserrat
.open-sans
@extend .body
font-family: fonts.$OpenSans
.public-sans
@extend .body
font-family: fonts.$PublicSans

View file

@ -0,0 +1,27 @@
.input
font-size: 1rem
padding: 0.5rem 1rem
width: 100%
border: 2px solid #ccc
border-radius: 4px
outline: none
transition: border-color 0.3s, box-shadow 0.3s
&:focus
border-color: #3377AC
box-shadow: 0 0 5px rgba(51, 119, 168, 0.3)
&::placeholder
color: #888
font-style: italic
&:disabled
background-color: #f0f0f0
border-color: #ddd
&--error
border-color: #ff4d4f
box-shadow: 0 0 5px rgba(255, 77, 79, 0.3)
&:focus
border-color: #e81123

View file

@ -0,0 +1,3 @@
a
text-decoration: none
color: inherit

View file

@ -0,0 +1,20 @@
@use '/src/styles/variables.sass' as vars
@use 'sass:color'
.modal
display: flex
justify-content: center
align-items: center
position: fixed
top: 0
left: 0
width: 100%
height: 100%
backdrop-filter: blur(20px)
background-color: rgba(color.adjust(vars.$background, $blackness: 5%), 0.6)
z-index: 999
&__content
border-radius: 8px
padding: 2rem
position: relative

View file

@ -0,0 +1,7 @@
.nav
position: fixed
top: 0
width: 100%
padding: 1rem 0
// margin: 5rem

View file

@ -0,0 +1,13 @@
.page
margin: 2rem
height: auto
min-height: 90vh
.column
@extend .page
display: flex
flex-direction: column
.row
@extend .column
flex-direction: row

View file

@ -0,0 +1,47 @@
.row-left
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: flex-start
align-items: center
align-content: center
.row-center
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: center
align-items: center
align-content: center
.row-right
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: flex-end
align-items: center
align-content: center
.row-split
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: space-between
align-items: center
align-content: center
.row-spaced
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: space-around
align-items: center
align-content: center
.row-even
display: flex
flex-direction: row
flex-wrap: wrap
justify-content: space-evenly
align-items: center
align-content: center

View file

@ -0,0 +1 @@
@use '/src/styles/breakpoint.sass'

23
frontend/src/app.tsx Normal file
View file

@ -0,0 +1,23 @@
import { MetaProvider, Title } from '@solidjs/meta'
import { Router } from '@solidjs/router'
import { FileRoutes } from '@solidjs/start/router'
import { Suspense } from 'solid-js'
import './styles/app.sass'
export default () => {
return (
<Router
root={(props) => (
<MetaProvider>
<Title>Dasig - Solid</Title>
{/* <a href="/">Index</a>
<a href="/about">About</a> */}
<Suspense>{props.children}</Suspense>
</MetaProvider>
)}
>
<FileRoutes />
</Router>
)
}

View file

@ -0,0 +1,46 @@
.counter
font-family: inherit
font-size: inherit
display: flex
flex-direction: column
align-items: center
gap: 1rem
margin: 2rem
color: white
border: 1px solid rgba(22, 34, 60, 0.5)
padding: 1rem 2rem
border-radius: 16px
background: rgba(134, 152, 217, 0.1)
width: 3rem
&__display
font-size: 1.75rem
font-weight: bold
&__buttons
display: flex
justify-content: center
gap: 0.25rem
&__decrement
width: 2rem
height: 2.25rem
padding: auto
font-size: 1rem
font-weight: bold
cursor: pointer
text-decoration: none
background-color: rgba(86, 14, 14, 0.915)
border-radius: 8px
color: white
border: 1px solid rgba(255,255,255,0.2)
&:active
transform: scale(0.95)
&__increment
@extend .counter__decrement
background-color: rgb(14, 42, 86, 0.915)
&:active
transform: scale(0.95)

View file

@ -0,0 +1,30 @@
import './Counter.sass'
import { createSignal } from 'solid-js'
let [count, setCount] = createSignal(0)
const increment = () => {
setCount(count() + 1)
}
const decrement = () => {
setCount(count() - 1)
}
export default () => {
return (
<>
<section class="counter">
<div class="counter__display">{count()}</div>
<div class="counter__buttons">
<button class="counter__decrement" onClick={decrement}>
-
</button>
<button class="counter__increment" onClick={increment}>
+
</button>
</div>
</section>
</>
)
}

View file

@ -0,0 +1,4 @@
// @refresh reload
import { mount, StartClient } from "@solidjs/start/client";
mount(() => <StartClient />, document.getElementById("app")!);

View file

@ -0,0 +1,23 @@
// // src/entry-server.tsx
// import { createHandler, StartServer } from '@solidjs/start/server'
// import dotenv from 'dotenv'
// dotenv.config({ path: 'env/.env.site' })
// import { HTML } from './_dasig'
// const websiteName = process.env.WEBSITE_NAME || 'Dasig - Solid'
// const websiteDescription = process.env.WEBSITE_DESCRIPTION || 'A template for fast development (Solid Version)'
// const author = process.env.AUTHOR || 'Patrick Alvin Alcala'
// const font = process.env.FONT
// export default createHandler(() => <StartServer document={({ assets, children, scripts }) => <HTML name={websiteName} description={websiteDescription} author={author} children={children} assets={assets} scripts={scripts} font={font} />} />)
import { createHandler, StartServer } from '@solidjs/start/server'
import { $websiteName, $websiteDescription, $yourName, $font } from '../configs/config.site'
import { HTML } from '~/@dasig'
const websiteName = $websiteName.get() || 'Dasig - Solid'
const websiteDescription = $websiteDescription.get() || 'A template for fast development (Solid Version)'
const author = $yourName.get() || 'Patrick Alvin Alcala'
const font = $font.get()
export default createHandler(() => <StartServer document={({ assets, children, scripts }) => <HTML name={websiteName} description={websiteDescription} author={author} children={children} assets={assets} scripts={scripts} font={font} />} />)

1
frontend/src/global.d.ts vendored Normal file
View file

@ -0,0 +1 @@
/// <reference types="@solidjs/start/env" />

View file

@ -0,0 +1,19 @@
import { Title } from "@solidjs/meta";
import { HttpStatusCode } from "@solidjs/start";
export default function NotFound() {
return (
<main>
<Title>Not Found</Title>
<HttpStatusCode code={404} />
<h1>Page Not Found</h1>
<p>
Visit{" "}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{" "}
to learn how to build SolidStart apps.
</p>
</main>
);
}

View file

@ -0,0 +1,10 @@
import { Title } from "@solidjs/meta";
export default function About() {
return (
<main>
<Title>About</Title>
<h1>About</h1>
</main>
);
}

View file

@ -0,0 +1,4 @@
@use '../styles/variables' as vars
.h1
color: vars.$accentColor

View file

@ -0,0 +1,15 @@
import './index.sass'
import Counter from '~/components/Counter/Counter'
import { Page, Column } from '~/@dasig'
export default () => {
return (
<Page title="Dasig - Index">
<Column>
<h1>DASIG</h1>
<h4>A next level development for pure speed</h4>
<Counter />
</Column>
</Page>
)
}

View file

@ -0,0 +1,34 @@
@use './global'
@use './variables'
:root
background-color: variables.$background
a
margin-right: 1rem
main
text-align: center
padding: 1em
margin: 0 auto
h1
color: #335d92
text-transform: uppercase
font-size: 4rem
font-weight: 100
line-height: 1.1
margin: 4rem auto
max-width: 14rem
p
max-width: 14rem
margin: 2rem auto
line-height: 1.35
@media (min-width: 480px)
h1
max-width: none
p
max-width: none

View file

@ -0,0 +1,51 @@
$mobile: 575.98px
$tablet: 768px
$desktop: 1440px
.on-desktop-only
@media only screen and (min-width: 0px) and (max-width: $desktop)
display: none
@media only screen and (min-width: $desktop)
display: block
.on-tablet-only
@media only screen and (min-width: 0px) and (max-width: $tablet)
display: none
@media only screen and (min-width: $tablet) and (max-width: $desktop)
display: block
@media only screen and (min-width: $desktop)
display: none
.on-mobile-only
@media only screen and (max-width: $mobile)
display: block
@media only screen and (min-width: $tablet)
display: none
.on-desktop-tablet-only
@media only screen and (min-width: 0px) and (max-width: $tablet)
display: none
@media only screen and (min-width: $tablet)
display: block
.on-desktop-mobile-only
@media only screen and (min-width: 0px) and (max-width: $mobile)
display: block
@media only screen and (min-width: $mobile) and (max-width: $desktop)
display: none
@media only screen and (min-width: $desktop)
display: block
.on-tablet-mobile-only
@media only screen and (min-width: 0px) and (max-width: $desktop)
display: block
@media only screen and (min-width: $desktop)
display: none

View file

@ -0,0 +1,45 @@
$Roboto: Roboto, sans-serif
$Inter: Inter, sans-serif
$Montserrat: Montserrat, sans-serif
$OpenSans: 'Open Sans', sans-serif
$PublicSans: 'Public Sans', sans-serif
@font-face
font-family: 'Roboto'
font-style: normal
font-display: swap
font-weight: 100 900
src: url(https://cdn.jsdelivr.net/fontsource/fonts/roboto:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD
@font-face
font-family: 'Inter'
font-style: normal
font-display: swap
font-weight: 100 900
src: url(https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD
@font-face
font-family: 'Montserrat'
font-style: normal
font-display: swap
font-weight: 100 900
src: url(https://cdn.jsdelivr.net/fontsource/fonts/montserrat:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD
@font-face
font-family: 'Open Sans'
font-style: normal
font-display: swap
font-weight: 300 800
src: url(https://cdn.jsdelivr.net/fontsource/fonts/open-sans:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD
@font-face
font-family: 'Public Sans'
font-style: normal
font-display: swap
font-weight: 100 900
src: url(https://cdn.jsdelivr.net/fontsource/fonts/public-sans:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD

View file

@ -0,0 +1,9 @@
.background
position: absolute
top: 0
left: 0
width: 100vw
height: 100vh
object-fit: cover
z-index: -1
opacity: 1

View file

@ -0,0 +1,16 @@
@use 'sass:color'
$background: #09111f
$textColor: #f0f8ff
$fontSize: 1rem
$borderMargin: 2rem
$primaryColor: #0075BB
$secondaryColor: #57687F
$accentColor: #00887C
$infoColor: #0082A4
$successColor: #009435
$warningColor: #E5B400
$errorColor: #E8595C

19
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"allowJs": true,
"strict": true,
"noEmit": true,
"types": ["vinxi/types/client"],
"isolatedModules": true,
"paths": {
"~/*": ["./src/*"]
}
}
}