feat: initial commit
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package pages
|
||||
|
||||
templ Index() {
|
||||
@PageSkeleton("Time Share") {
|
||||
<div class="flex flex-col p-10 w-full h-screen justify-center items-center">
|
||||
<h1 class="text-4xl font-semibold">Time Share</h1>
|
||||
<p><a class="text-md underline" href="https://lukaswerner.com">Lukas Werner</a></p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package pages
|
||||
|
||||
import "git.hafen.run/lukas/timeshare/components/toast"
|
||||
|
||||
templ PageSkeleton(title string) {
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<!-- Tailwind CSS (output) -->
|
||||
<link href="/assets/css/output.css" rel="stylesheet"/>
|
||||
<title>{ title }</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/images/apple-touch-icon.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png"/>
|
||||
<link rel="manifest" href="/assets/site.webmanifest"/>
|
||||
<style>
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation-duration: 0.5s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="p-0 m-0">
|
||||
{ children... }
|
||||
@toast.Script()
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.hafen.run/lukas/timeshare/components/button"
|
||||
"git.hafen.run/lukas/timeshare/components/label"
|
||||
"git.hafen.run/lukas/timeshare/components/radio"
|
||||
"git.hafen.run/lukas/timeshare/components/toast"
|
||||
)
|
||||
|
||||
type Expiry struct {
|
||||
DurationCode string
|
||||
DurationName string
|
||||
}
|
||||
|
||||
templ Upload(expirations []Expiry, uploadedLink string) {
|
||||
@PageSkeleton("Upload - Time Share") {
|
||||
if uploadedLink != "" {
|
||||
@toast.Toast(toast.Props{
|
||||
Title: "Share Created!",
|
||||
Description: fmt.Sprintf(`<a class="underline" href="%s">%s</a>`, uploadedLink, uploadedLink),
|
||||
Variant: toast.VariantSuccess,
|
||||
Duration: 120000, // 2 min
|
||||
Position: toast.PositionBottomCenter,
|
||||
Dismissible: true,
|
||||
Icon: true,
|
||||
})
|
||||
}
|
||||
<div class="flex flex-col p-10 w-full h-screen justify-center items-center">
|
||||
<form class="flex flex-col items-center gap-2" method="POST" enctype="multipart/form-data">
|
||||
<h1 class="text-3xl font-medium pb-4">Time Share Upload</h1>
|
||||
<input type="file" class="hidden" id="files" name="files" multiple/>
|
||||
<div class="border-2 border-dashed rounded-xl border-gray-400 flex flex-col justify-center items-center p-10" id="drop_zone">
|
||||
<p id="desc" class="w-[39ch] text-center">Drop files onto here or click to upload</p>
|
||||
</div>
|
||||
<script>
|
||||
let drop_zone = document.getElementById("drop_zone");
|
||||
let desc = document.getElementById("desc");
|
||||
let fileInput = document.getElementById("files");
|
||||
drop_zone.addEventListener("click", function (ev) {
|
||||
fileInput.click();
|
||||
})
|
||||
drop_zone.addEventListener("drop", function (ev) {
|
||||
ev.preventDefault();
|
||||
drop_zone.classList.remove('dragover');
|
||||
const dt = ev.dataTransfer;
|
||||
if (!dt) return
|
||||
|
||||
const files = Array.from(dt.files); // iterable
|
||||
|
||||
const newDT = new DataTransfer();
|
||||
files.forEach(f => newDT.items.add(f));
|
||||
fileInput.files = newDT.files;
|
||||
desc.innerText = `${fileInput.files.length} File`
|
||||
if (fileInput.files.length > 1) {
|
||||
desc.innerText += "s"
|
||||
}
|
||||
|
||||
});
|
||||
drop_zone.addEventListener("dragover", function (e) {
|
||||
drop_zone.classList.add('dragover');
|
||||
e.preventDefault();
|
||||
});
|
||||
drop_zone.addEventListener("dragleave", function (e) {
|
||||
drop_zone.classList.remove('dragover');
|
||||
e.preventDefault();
|
||||
});
|
||||
</script>
|
||||
<style>.dragover {border-color: #00C950;}</style>
|
||||
<div class="flex flex-col gap-3 w-full">
|
||||
<p>Expiration:</p>
|
||||
<div class="pl-2 flex flex-col gap-3">
|
||||
for i, expiry := range expirations {
|
||||
<div class="flex items-start gap-3">
|
||||
@radio.Radio(radio.Props{
|
||||
ID: expiry.DurationCode,
|
||||
Name: "expiry",
|
||||
Value: expiry.DurationCode,
|
||||
Checked: i == 0,
|
||||
})
|
||||
@label.Label(label.Props{
|
||||
For: expiry.DurationCode,
|
||||
}) {
|
||||
{ expiry.DurationName }
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@button.Button(button.Props{
|
||||
Type: "submit",
|
||||
}) {
|
||||
Upload
|
||||
}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user