initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
filething
|
||||||
12
Dockerfile
Normal file
12
Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
FROM golang:alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
RUN apk add npm
|
||||||
|
|
||||||
|
RUN go generate
|
||||||
|
RUN go build main.go
|
||||||
|
|
||||||
|
ENTRYPOINT main.go
|
||||||
35
docker-compose.yml
Normal file
35
docker-compose.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: filething
|
||||||
|
|
||||||
|
networks:
|
||||||
|
filething:
|
||||||
|
external: false
|
||||||
|
|
||||||
|
services:
|
||||||
|
filething:
|
||||||
|
build: .
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- DB_HOST=db:5432
|
||||||
|
- DB_NAME=filething
|
||||||
|
- DB_USER=filething
|
||||||
|
- DB_PASSWD=filething
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- filething
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
ports:
|
||||||
|
- "1323:1323"
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:14
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=filething
|
||||||
|
- POSTGRES_PASSWD=filething
|
||||||
|
- POSTGRES_DB=filething
|
||||||
|
networks:
|
||||||
|
- filething
|
||||||
|
volumes:
|
||||||
|
- ./postgres:/var/lib/postgresql/data
|
||||||
16
go.mod
Normal file
16
go.mod
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
module filething
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/labstack/echo/v4 v4.12.0 // indirect
|
||||||
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
golang.org/x/crypto v0.22.0 // indirect
|
||||||
|
golang.org/x/net v0.24.0 // indirect
|
||||||
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
)
|
||||||
23
go.sum
Normal file
23
go.sum
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||||
|
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||||
|
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
|
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
|
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
59
main.go
Normal file
59
main.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
//go:generate npm --prefix ./ui run generate
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"filething/ui"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
e := echo.New()
|
||||||
|
|
||||||
|
api := e.Group("/api")
|
||||||
|
{
|
||||||
|
api.GET("/hello", func(c echo.Context) error {
|
||||||
|
return c.JSON(http.StatusOK, map[string]string{"message": "Hello, World!!!"})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
e.GET("/*", echo.StaticDirectoryHandler(ui.DistDirFS, false))
|
||||||
|
|
||||||
|
e.HTTPErrorHandler = customHTTPErrorHandler
|
||||||
|
|
||||||
|
e.Logger.Fatal(e.Start(":1323"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func customHTTPErrorHandler(err error, c echo.Context) {
|
||||||
|
code := http.StatusInternalServerError
|
||||||
|
if he, ok := err.(*echo.HTTPError); ok {
|
||||||
|
code = he.Code
|
||||||
|
}
|
||||||
|
c.Logger().Error(err)
|
||||||
|
errorPage := fmt.Sprintf("%d.html", code)
|
||||||
|
file, err := ui.DistDirFS.Open(errorPage)
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileInfo, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileBuf := make([]byte, fileInfo.Size())
|
||||||
|
_, err = file.Read(fileBuf)
|
||||||
|
defer func() {
|
||||||
|
if err := file.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
c.Logger().Error(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.HTML(http.StatusNotFound, string(fileBuf))
|
||||||
|
}
|
||||||
24
ui/.gitignore
vendored
Normal file
24
ui/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Nuxt dev/build outputs
|
||||||
|
.output
|
||||||
|
.data
|
||||||
|
.nuxt
|
||||||
|
.nitro
|
||||||
|
.cache
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Node dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
.fleet
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Local env files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
75
ui/README.md
Normal file
75
ui/README.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Nuxt 3 Minimal Starter
|
||||||
|
|
||||||
|
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Make sure to install the dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Server
|
||||||
|
|
||||||
|
Start the development server on `http://localhost:3000`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run dev
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
Build the application for production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run build
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Locally preview production build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run preview
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm run preview
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn preview
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||||
5
ui/app.vue
Normal file
5
ui/app.vue
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<NuxtPage />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
3
ui/assets/css/main.css
Normal file
3
ui/assets/css/main.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
BIN
ui/bun.lockb
Executable file
BIN
ui/bun.lockb
Executable file
Binary file not shown.
2
ui/components/Nav.vue
Normal file
2
ui/components/Nav.vue
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<template>
|
||||||
|
</template>
|
||||||
14
ui/embed.go
Normal file
14
ui/embed.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Package ui handles the frontend embedding
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed all:.output/public
|
||||||
|
var distDir embed.FS
|
||||||
|
|
||||||
|
// DistDirFS contains the embedded dist directory files (without the "dist" prefix)
|
||||||
|
var DistDirFS = echo.MustSubFS(distDir, ".output/public")
|
||||||
25
ui/nuxt.config.ts
Normal file
25
ui/nuxt.config.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
compatibilityDate: '2024-04-03',
|
||||||
|
|
||||||
|
css: ['~/assets/css/main.css'],
|
||||||
|
|
||||||
|
ssr: true,
|
||||||
|
|
||||||
|
modules: [
|
||||||
|
'@nuxtjs/color-mode',
|
||||||
|
],
|
||||||
|
|
||||||
|
colorMode: {
|
||||||
|
classSuffix: ''
|
||||||
|
},
|
||||||
|
|
||||||
|
devtools: { enabled: true },
|
||||||
|
|
||||||
|
postcss: {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
22
ui/package.json
Normal file
22
ui/package.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "nuxt-app",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"generate": "nuxt generate",
|
||||||
|
"preview": "nuxt preview",
|
||||||
|
"postinstall": "nuxt prepare"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxtjs/color-mode": "^3.4.4",
|
||||||
|
"nuxt": "^3.13.0",
|
||||||
|
"vue": "latest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
|
"postcss": "^8.4.44",
|
||||||
|
"tailwindcss": "^3.4.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
12
ui/pages/home.vue
Normal file
12
ui/pages/home.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Nav />
|
||||||
|
WOAH IS THAT FRICKING SCOTT THE WOZ DUDE
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
11
ui/pages/index.vue
Normal file
11
ui/pages/index.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
OMG IS THAT SCOTT THE WOZ?!?!?!?!?!?!??!?!??!?!?!?!?!?!?
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
38
ui/pages/login.vue
Normal file
38
ui/pages/login.vue
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<script setup>
|
||||||
|
console.log(useCookie("sessionToken").value)
|
||||||
|
|
||||||
|
if (useCookie("sessionToken").value) {
|
||||||
|
await navigateTo('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
let email = ref('')
|
||||||
|
let password = ref('')
|
||||||
|
|
||||||
|
const submitForm = async () => {
|
||||||
|
await useFetch('/api/login', {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
"email": email.value,
|
||||||
|
"password": password.value,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await navigateTo('/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen min-w-screen grid place-content-center">
|
||||||
|
<div class="flex flex-col max-w-72 w-full text-center">
|
||||||
|
<input
|
||||||
|
class="py-2 px-4 resize-none rounded-md my-2 border-gray-200 dark:border-dark-gray-800 focus:border-gray-300 dark:focus:border-dark-gray-800 border focus:outline-none placeholder:italic placeholder:text-slate-500 dark:placeholder:text-gray-300"
|
||||||
|
v-model="email" type="email" placeholder="Email..." />
|
||||||
|
<input
|
||||||
|
class="py-2 px-4 resize-none rounded-md my-2 border-gray-200 dark:border-dark-gray-800 focus:border-gray-300 dark:focus:border-dark-gray-800 border focus:outline-none placeholder:italic placeholder:text-slate-500 dark:placeholder:text-gray-300"
|
||||||
|
v-model="password" type="password" placeholder="Password..." />
|
||||||
|
<button @click="submitForm" class="py-2 px-4 bg-blue-500 text-white rounded-md">Login</button>
|
||||||
|
<p>Or <NuxtLink to="/signup" class="text-pink-600">Sign up</NuxtLink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
36
ui/pages/signup.vue
Normal file
36
ui/pages/signup.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<script setup>
|
||||||
|
if (useCookie("sessionToken").value) {
|
||||||
|
await navigateTo('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
let email = ref('')
|
||||||
|
let password = ref('')
|
||||||
|
|
||||||
|
const submitForm = async () => {
|
||||||
|
await useFetch('/api/signup', {
|
||||||
|
method: 'POST',
|
||||||
|
body: {
|
||||||
|
"email": email.value,
|
||||||
|
"password": password.value,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await navigateTo('/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="min-h-screen min-w-screen grid place-content-center">
|
||||||
|
<div class="flex flex-col max-w-72 w-full text-center">
|
||||||
|
<input
|
||||||
|
class="py-2 px-4 resize-none rounded-md my-2 border-gray-200 dark:border-dark-gray-800 focus:border-gray-300 dark:focus:border-dark-gray-800 border focus:outline-none placeholder:italic placeholder:text-slate-500 dark:placeholder:text-gray-300"
|
||||||
|
v-model="email" type="email" placeholder="Email..." />
|
||||||
|
<input
|
||||||
|
class="py-2 px-4 resize-none rounded-md my-2 border-gray-200 dark:border-dark-gray-800 focus:border-gray-300 dark:focus:border-dark-gray-800 border focus:outline-none placeholder:italic placeholder:text-slate-500 dark:placeholder:text-gray-300"
|
||||||
|
v-model="password" type="password" placeholder="Password..." />
|
||||||
|
<button @click="submitForm" class="py-2 px-4 bg-blue-500 text-white rounded-md">Signup</button>
|
||||||
|
<p>Or <NuxtLink to="/login" class="text-pink-600">Log in</NuxtLink>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
BIN
ui/public/favicon.ico
Normal file
BIN
ui/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
1
ui/public/robots.txt
Normal file
1
ui/public/robots.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
15
ui/tailwind.config.js
Normal file
15
ui/tailwind.config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"./components/**/*.{js,vue,ts}",
|
||||||
|
"./layouts/**/*.vue",
|
||||||
|
"./pages/**/*.vue",
|
||||||
|
"./plugins/**/*.{js,ts}",
|
||||||
|
"./app.vue",
|
||||||
|
"./error.vue",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
4
ui/tsconfig.json
Normal file
4
ui/tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// https://nuxt.com/docs/guide/concepts/typescript
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user