more polish, add picocss, add more js and web features
This commit is contained in:
parent
a5b6232c77
commit
ce47b12e09
25 changed files with 593 additions and 1862 deletions
9
examples/docker-compose.yml
Normal file
9
examples/docker-compose.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
services:
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: example
|
||||||
|
POSTGRES_USER: go-urlsh
|
||||||
|
POSTGRES_DB: go-urlsh
|
|
@ -58,6 +58,7 @@ func SetupFiber() error {
|
||||||
|
|
||||||
fiberapp.Get("/admin/", web.HandleAdminLinkIndexGet)
|
fiberapp.Get("/admin/", web.HandleAdminLinkIndexGet)
|
||||||
fiberapp.Get("/admin/links/new", web.HandleAdminLinkNewGet)
|
fiberapp.Get("/admin/links/new", web.HandleAdminLinkNewGet)
|
||||||
|
fiberapp.Get("/admin/links/edit/:id", web.HandleAdminLinkEditGet)
|
||||||
|
|
||||||
fiberapp.Static("/admin/", "./web")
|
fiberapp.Static("/admin/", "./web")
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,62 @@
|
||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"codeberg.org/lauralani/go-urlsh/internal/db"
|
||||||
|
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
||||||
"codeberg.org/lauralani/go-urlsh/models"
|
"codeberg.org/lauralani/go-urlsh/models"
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleAdminLinkNewGet(c *fiber.Ctx) error {
|
func HandleAdminLinkNewGet(c *fiber.Ctx) error {
|
||||||
return c.Render("add_link", nil)
|
return c.Render("add_link", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleAdminLinkIndexGet(c *fiber.Ctx) error {
|
func HandleAdminLinkEditGet(c *fiber.Ctx) error {
|
||||||
var links []models.Link
|
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
|
||||||
|
c.Location("/admin/")
|
||||||
err := models.DB.NewSelect().Model(&links).Scan(context.Background())
|
c.Status(fiber.StatusSeeOther)
|
||||||
if err != nil {
|
return nil
|
||||||
return fmt.Errorf("error querying links: %v", err.Error())
|
}
|
||||||
|
|
||||||
|
var link = new(models.Link)
|
||||||
|
var id = c.Params("id", "")
|
||||||
|
|
||||||
|
if id == "" {
|
||||||
|
log.Println("[HandleAdminLinkEditGet] no id param given")
|
||||||
|
return fiber.NewError(fiber.StatusBadRequest, "400 Bad Request")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := models.DB.NewSelect().Model(link).Where("id = ?", id).Scan(context.Background())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
log.Printf("[HandleAdminLinkEditGet] Shortlink %v not found\n", id)
|
||||||
|
return fiber.NewError(fiber.StatusNotFound, "404 Not Found")
|
||||||
|
} else {
|
||||||
|
log.Printf("[HandleAdminLinkEditGet] Error querying Shortlink %v from database: %v\n", id, err)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, "500 Internal Server Error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Render("edit_link", link)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleAdminLinkIndexGet(c *fiber.Ctx) error {
|
||||||
|
if !db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
|
||||||
|
c.Location("/admin/login")
|
||||||
|
c.Status(fiber.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
var links []models.Link
|
||||||
|
|
||||||
|
err := models.DB.NewSelect().Model(&links).Scan(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error querying links: %v", err.Error())
|
||||||
|
}
|
||||||
|
return c.Render("links", links)
|
||||||
}
|
}
|
||||||
return c.Render("links", links)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"codeberg.org/lauralani/go-urlsh/internal/db"
|
||||||
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
"codeberg.org/lauralani/go-urlsh/internal/misc"
|
||||||
"codeberg.org/lauralani/go-urlsh/models"
|
"codeberg.org/lauralani/go-urlsh/models"
|
||||||
"context"
|
"context"
|
||||||
|
@ -31,8 +32,14 @@ func HandleAdminLoginPost(c *fiber.Ctx) error {
|
||||||
|
|
||||||
if passwordsum == user.PasswordHash {
|
if passwordsum == user.PasswordHash {
|
||||||
// Passwords match
|
// Passwords match
|
||||||
|
var expires time.Time
|
||||||
|
|
||||||
|
if login.Remember == "on" {
|
||||||
|
expires = time.Now().Add(30 * 24 * time.Hour)
|
||||||
|
} else {
|
||||||
|
expires = time.Now().Add(24 * time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
expires := time.Now().Add(30 * 24 * time.Hour)
|
|
||||||
key := uuid.New().String()
|
key := uuid.New().String()
|
||||||
dblogin := new(models.Login)
|
dblogin := new(models.Login)
|
||||||
|
|
||||||
|
@ -68,5 +75,11 @@ func HandleAdminLoginPost(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleAdminLoginGet(c *fiber.Ctx) error {
|
func HandleAdminLoginGet(c *fiber.Ctx) error {
|
||||||
return c.Render("login", nil)
|
if db.IsCookieValid(c.Cookies(misc.CookieName, "")) {
|
||||||
|
c.Location("/admin/")
|
||||||
|
c.Status(fiber.StatusSeeOther)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return c.Render("login", nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,5 @@ type Login struct {
|
||||||
type LoginRequest struct {
|
type LoginRequest struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
|
Remember string `json:"remember"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,74 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
<title>Add new Shortlink - go-urlsh</title>
|
<title>Add new Shortlink - go-urlsh</title>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/style.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/link_add.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<form action="javascript:void(0);" style="margin-top: 2em">
|
<nav class="container-fluid">
|
||||||
<fieldset id="form_fields">
|
<ul>
|
||||||
<legend>Add a new Shortlink</legend>
|
<li>
|
||||||
<p>* shows a required field</p>
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
<label for="linkname">Shortlink Name (leave empty for random)</label>
|
</li>
|
||||||
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/">Links</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main class="container" style="padding: 0">
|
||||||
|
<form action="javascript:HandleSubmit();" style="margin: 0">
|
||||||
|
<fieldset id="form_fields">
|
||||||
|
<hgroup>
|
||||||
|
<h1>Add new shortlink</h1>
|
||||||
|
<h2><i style="color: red;">*</i> marks required fields</h2>
|
||||||
|
</hgroup>
|
||||||
|
<label for="linkname">Shortlink Name (leave empty for random)</label>
|
||||||
|
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
||||||
|
|
||||||
<label for="link">Link *</label>
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
<input type="text" name="link" id="link" placeholder="https://" style="width: 97%" onchange="HandleChange()">
|
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleChange()">
|
||||||
|
|
||||||
<label for="description">Description</label>
|
<label for="description">Description</label>
|
||||||
<input type="text" name="description" id="description" placeholder="" style="width: 97%">
|
<input type="text" name="description" id="description" placeholder="">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<input type="submit" id="submit" value="Add" onclick="HandleSubmit()" style="margin-top: 1em;">
|
<input type="submit" id="submit" value="Add" style="margin-top: 1em;">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<dialog id="dialog-info">
|
||||||
|
<h2 id="dialog-heading"></h2>
|
||||||
|
<p id="dialog-text"></p>
|
||||||
|
<form method="dialog">
|
||||||
|
<button>Close</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<dialog id="dialog-info">
|
|
||||||
<h2 id="dialog-heading"></h2>
|
|
||||||
<p id="dialog-text"></p>
|
|
||||||
<form method="dialog">
|
|
||||||
<button>Close</button>
|
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>go-urlsh - <a href="/">Home</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="/admin/link_add.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
74
views/edit_link.tmpl
Normal file
74
views/edit_link.tmpl
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
|
<title>Edit Shortlink - go-urlsh</title>
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/link_add.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="container-fluid">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/">Links</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main class="container" style="padding: 0">
|
||||||
|
<form action="javascript:HandleSubmit();" style="margin: 0">
|
||||||
|
<fieldset id="form_fields">
|
||||||
|
<hgroup>
|
||||||
|
<h1>Edit shortlink</h1>
|
||||||
|
<h2><i style="color: red;">*</i> marks required fields</h2>
|
||||||
|
</hgroup>
|
||||||
|
<label for="linkname">Shortlink Name (to change this, delete the shortlink and add it again)</label>
|
||||||
|
<input type="text" name="linkname" id="linkname" value="{{.ID}}" data-tooltip="" readonly>
|
||||||
|
|
||||||
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
|
<input type="text" name="link" id="link" value="{{.URL}}">
|
||||||
|
|
||||||
|
<label for="description">Description</label>
|
||||||
|
<input type="text" name="description" id="description" value="{{.Description}}">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<input type="submit" id="submit" value="Save" style="margin-top: 1em;">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<dialog id="dialog-info">
|
||||||
|
<h2 id="dialog-heading"></h2>
|
||||||
|
<p id="dialog-text"></p>
|
||||||
|
<form method="dialog">
|
||||||
|
<button>Close</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
110
views/links.tmpl
110
views/links.tmpl
|
@ -1,57 +1,77 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
<title>Shortlinks - go-urlsh</title>
|
<title>Shortlinks - go-urlsh</title>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/style.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/links.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
td { vertical-align: middle; }
|
td {
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<nav class="container-fluid">
|
||||||
<a href="/admin/links/new"><button type="button" id="add-new-button">Add new Shortlink</button></a>
|
<ul>
|
||||||
|
<li>
|
||||||
<table>
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
<thead>
|
</li>
|
||||||
<tr>
|
</ul>
|
||||||
<th>Shortlink</th>
|
<ul>
|
||||||
<th>URL</th>
|
<li>
|
||||||
<th> </th>
|
<a href="/admin/links/new" style="color: greenyellow;">Add new Shortlink</a>
|
||||||
<th> </th>
|
</li>
|
||||||
</tr>
|
<li>
|
||||||
</thead>
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
<tbody>
|
</li>
|
||||||
{{range .}}
|
<li>
|
||||||
<tr>
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
<td><a href="#" onclick="HandleCopy('{{.ID}}')">{{.ID}}</a></td>
|
</li>
|
||||||
<td><a href="{{.URL}}" target="_blank">{{.URL}}</a></td>
|
<li>
|
||||||
<td style="text-align: right;">
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
<button type="button" id="edit-button" onclick="HandleEdit('{{.ID}}')">
|
</li>
|
||||||
Edit
|
</ul>
|
||||||
</button>
|
</nav>
|
||||||
</td>
|
<main class="container">
|
||||||
<td style="text-align: right;">
|
<table class="n-table">
|
||||||
<button type="button" id="delete-button" onclick="HandleDelete('{{.ID}}')">
|
<thead>
|
||||||
Delete
|
<tr>
|
||||||
</button>
|
<th>Shortlink</th>
|
||||||
</td>
|
<th>URL</th>
|
||||||
</tr>
|
<th> </th>
|
||||||
{{end}}
|
<th> </th>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .}}
|
||||||
<footer>
|
<tr>
|
||||||
<p>go-urlsh - <a href="/admin/">Home</a> -
|
<td><a href="javascript: HandleCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
|
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
|
<td style="text-align: right;">
|
||||||
</p>
|
<a href="/admin/links/edit/{{.ID}}">
|
||||||
</footer>
|
Edit
|
||||||
|
</a>
|
||||||
<script src="/admin/links.js"></script>
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
<a href="javascript: HandleDelete('{{.ID}}');">
|
||||||
|
Delete
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
|
@ -1,22 +1,43 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
<title>Page Title</title>
|
<title>Login - go-urlsh</title>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/style.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h3 id="form-elements">Form elements</h3>
|
<main class="container">
|
||||||
<form method="post" action="/admin/login">
|
<article class="grid">
|
||||||
<label for="username">Username</label>
|
<div>
|
||||||
<input type="text" name="username" id="username" placeholder="username">
|
<hgroup>
|
||||||
|
<h1 style='--color: var(--h1-color); font-weight: var(--font-weight); font-size: var(--font-size); font-family: var(--font-family);'>Sign in</h1>
|
||||||
|
</hgroup>
|
||||||
|
<form method="post" action="/admin/login" style="margin-bottom: 0;" autocomplete="off">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" name="username" id="username" placeholder="Username">
|
||||||
|
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="hidden" name="password" id="password" placeholder="password">
|
<input type="password" name="password" id="password" placeholder="*******">
|
||||||
|
|
||||||
<input type="submit" value="Login">
|
<fieldset>
|
||||||
</form>
|
<label for="remember">
|
||||||
|
<input type="checkbox" role="switch" id="remember" name="remember" />
|
||||||
|
Stay logged in
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<input type="submit" value="Login" class="contrast">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
8
views/partials/footer.tmpl
Normal file
8
views/partials/footer.tmpl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<footer class="container-fluid">
|
||||||
|
<small>
|
||||||
|
© 2023 Laura Kalb -
|
||||||
|
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank" class="secondary">Source Code</a> -
|
||||||
|
<a href="https://picocss.com" target="_blank" class="secondary">Theme: PicoCSS</a> -
|
||||||
|
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank" class="secondary">License</a>
|
||||||
|
</small>
|
||||||
|
</footer>
|
|
@ -1,49 +1,74 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
<title>Add new Shortlink - go-urlsh</title>
|
<title>Add new Shortlink - go-urlsh</title>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/simple.min.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/link_add.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<form action="javascript:void(0);" style="margin-top: 2em">
|
<nav class="container-fluid">
|
||||||
<fieldset id="form_fields">
|
<ul>
|
||||||
<legend>Add a new Shortlink</legend>
|
<li>
|
||||||
<p>* shows a required field</p>
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
<label for="linkname">Shortlink Name (leave empty for random)</label>
|
</li>
|
||||||
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/">Links</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main class="container" style="padding: 0">
|
||||||
|
<form action="javascript:HandleSubmit();" style="margin: 0">
|
||||||
|
<fieldset id="form_fields">
|
||||||
|
<hgroup>
|
||||||
|
<h1>Add new shortlink</h1>
|
||||||
|
<h2><i style="color: red;">*</i> marks required fields</h2>
|
||||||
|
</hgroup>
|
||||||
|
<label for="linkname">Shortlink Name (leave empty for random)</label>
|
||||||
|
<input type="text" name="linkname" id="linkname" placeholder="shortlink">
|
||||||
|
|
||||||
<label for="link">Link *</label>
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
<input type="text" name="link" id="link" placeholder="https://" style="width: 100%" onchange="HandleChange()">
|
<input type="text" name="link" id="link" placeholder="https://" onchange="HandleChange()">
|
||||||
|
|
||||||
<label for="description">Description</label>
|
<label for="description">Description</label>
|
||||||
<input type="text" name="description" id="description" placeholder="" style="width: 100%">
|
<input type="text" name="description" id="description" placeholder="">
|
||||||
|
|
||||||
<input type="submit" id="submit" value="Login" onclick="HandleSubmit()" disabled>
|
<div>
|
||||||
</fieldset>
|
|
||||||
|
<input type="submit" id="submit" value="Add" style="margin-top: 1em;">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<dialog id="dialog-info">
|
||||||
|
<h2 id="dialog-heading"></h2>
|
||||||
|
<p id="dialog-text"></p>
|
||||||
|
<form method="dialog">
|
||||||
|
<button>Close</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<dialog id="dialog-info">
|
|
||||||
<h2 id="dialog-heading"></h2>
|
|
||||||
<p id="dialog-text"></p>
|
|
||||||
<form method="dialog">
|
|
||||||
<button>Close</button>
|
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>go-urlsh - <a href="/">Home</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="/admin/links.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
74
web/custom.css
Normal file
74
web/custom.css
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* Grid */
|
||||||
|
body>main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: calc(100vh - 7rem);
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 576px) {
|
||||||
|
body>main {
|
||||||
|
padding: 1.25rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
body>main {
|
||||||
|
padding: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
body>main {
|
||||||
|
padding: 1.75rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div {
|
||||||
|
padding: 1.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
body>main {
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
article div {
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nav */
|
||||||
|
summary[role="link"].secondary:is([aria-current], :hover, :active, :focus) {
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--secondary-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.grid>div:nth-of-type(2) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
body>footer {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
74
web/link_edit.html
Normal file
74
web/link_edit.html
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
|
<title>Edit Shortlink - go-urlsh</title>
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/link_add.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="container-fluid">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/">Links</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main class="container" style="padding: 0">
|
||||||
|
<form action="javascript:HandleSubmit();" style="margin: 0">
|
||||||
|
<fieldset id="form_fields">
|
||||||
|
<hgroup>
|
||||||
|
<h1>Edit shortlink</h1>
|
||||||
|
<h2><i style="color: red;">*</i> marks required fields</h2>
|
||||||
|
</hgroup>
|
||||||
|
<label for="linkname">Shortlink Name (to change this, delete the shortlink and add it again)</label>
|
||||||
|
<input type="text" name="linkname" id="linkname" value="{{.ID}}" data-tooltip="" readonly>
|
||||||
|
|
||||||
|
<label for="link">Link <i style="color: red;">*</i></label>
|
||||||
|
<input type="text" name="link" id="link" value="{{.URL}}">
|
||||||
|
|
||||||
|
<label for="description">Description</label>
|
||||||
|
<input type="text" name="description" id="description" value="{{.Description}}">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<input type="submit" id="submit" value="Save" style="margin-top: 1em;">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<dialog id="dialog-info">
|
||||||
|
<h2 id="dialog-heading"></h2>
|
||||||
|
<p id="dialog-text"></p>
|
||||||
|
<form method="dialog">
|
||||||
|
<button>Close</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -1,54 +1,77 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||||
<title>Shortlinks - go-urlsh</title>
|
<title>Shortlinks - go-urlsh</title>
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||||
<link rel="stylesheet" href="/admin/style.css">
|
<link rel="stylesheet" href="/admin/pico.min.css">
|
||||||
|
<link rel="stylesheet" href="/admin/custom.css">
|
||||||
|
<script src="/admin/links.js" defer></script>
|
||||||
|
<script src="/admin/misc.js" defer></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
td {
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
|
|
||||||
<table>
|
<body>
|
||||||
<thead>
|
<nav class="container-fluid">
|
||||||
<tr>
|
<ul>
|
||||||
<th>Shortlink</th>
|
<li>
|
||||||
<th>URL</th>
|
<a href="/admin/" class="contrast"><strong>go-urlsh</strong></a>
|
||||||
<th> </th>
|
</li>
|
||||||
<th> </th>
|
</ul>
|
||||||
</tr>
|
<ul>
|
||||||
</thead>
|
<li>
|
||||||
<tbody>
|
<a href="/admin/links/new" style="color: greenyellow;">Add new Shortlink</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/admin/apikeys/">API Keys</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: void(0)" >Users (coming soon)</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="javascript: Logout()" style="color: red;">Logout</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main class="container">
|
||||||
|
<table class="n-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Shortlink</th>
|
||||||
|
<th>URL</th>
|
||||||
|
<th> </th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{{range .}}
|
{{range .}}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a onclick="HandleCopy('{{.id}}')">{{.ID}}</a></td>
|
<td><a href="javascript: HandleCopy('{{.ID}}');" data-tooltip="click to copy">{{.ID}}</a></td>
|
||||||
<td><a href="{{.URL}}" target="_blank">{{.URL}}</a></td>
|
<td><a href="{{.URL}}" target="_blank" {{if .Description}}data-tooltip="{{.Description}}"{{end}}>{{.URL}}</a></td>
|
||||||
|
<td style="text-align: right;">
|
||||||
<td>
|
<a href="/admin/links/edit/{{.ID}}">
|
||||||
<button type="button" id="edit-button" onclick="HandleEdit('{{.ID}}')">
|
Edit
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" /></svg>
|
</a>
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td style="text-align: right;">
|
||||||
<button type="button" id="delete-button" onclick="HandleDelete('{{.ID}}')">
|
<a href="javascript: HandleDelete('{{.ID}}');">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" /></svg>
|
Delete
|
||||||
</button>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</main>
|
||||||
|
{{template "partials/footer" .}}
|
||||||
<footer>
|
|
||||||
<p>go-urlsh - <a href="/">Home</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh" target="_blank">Source Code</a> -
|
|
||||||
<a href="https://codeberg.org/lauralani/go-urlsh/src/branch/main/LICENSE" target="_blank">License</a>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="/admin/links.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
4
web/misc.js
Normal file
4
web/misc.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
function Logout() {
|
||||||
|
document.cookie = 'gourlsh_auth=; Max-Age=-1; path=/; domain=' + location.hostname;
|
||||||
|
document.location = "/admin/login"
|
||||||
|
}
|
5
web/pico.classless.min.css
vendored
Normal file
5
web/pico.classless.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
web/pico.classless.min.css.gz
Normal file
BIN
web/pico.classless.min.css.gz
Normal file
Binary file not shown.
1
web/pico.classless.min.css.map
Normal file
1
web/pico.classless.min.css.map
Normal file
File diff suppressed because one or more lines are too long
BIN
web/pico.classless.min.css.map.gz
Normal file
BIN
web/pico.classless.min.css.map.gz
Normal file
Binary file not shown.
5
web/pico.min.css
vendored
Normal file
5
web/pico.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
web/pico.min.css.gz
Normal file
BIN
web/pico.min.css.gz
Normal file
Binary file not shown.
1
web/pico.min.css.map
Normal file
1
web/pico.min.css.map
Normal file
File diff suppressed because one or more lines are too long
BIN
web/pico.min.css.map.gz
Normal file
BIN
web/pico.min.css.map.gz
Normal file
Binary file not shown.
1689
web/style.css
1689
web/style.css
File diff suppressed because it is too large
Load diff
BIN
web/style.css.gz
BIN
web/style.css.gz
Binary file not shown.
Loading…
Reference in a new issue