[add] docker instructions, [add] metadata gathering, [add] screenshots
38
Dockerfile
@ -1,19 +1,35 @@
|
||||
FROM alpine:edge AS build
|
||||
RUN apk add --no-cache --update go gcc g++
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
# Certificate Store
|
||||
FROM alpine as certs
|
||||
RUN apk update && apk add ca-certificates
|
||||
|
||||
# Copy Resources
|
||||
# Build Image
|
||||
FROM --platform=$BUILDPLATFORM golang:1.20 AS build
|
||||
|
||||
# Install Dependencies
|
||||
RUN apt-get update -y
|
||||
RUN apt install -y gcc-x86-64-linux-gnu
|
||||
|
||||
# Create Package Directory
|
||||
WORKDIR /src
|
||||
RUN mkdir -p /opt/bookmanager
|
||||
RUN cp -a ./templates /opt/bookmanager/templates
|
||||
RUN cp -a ./assets /opt/bookmanager/assets
|
||||
|
||||
# Download Dependencies & Compile
|
||||
RUN go mod download
|
||||
RUN CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build -o /opt/bookmanager/server
|
||||
# Cache Dependencies & Compile
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
RUN --mount=target=. \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
--mount=type=cache,target=/go/pkg \
|
||||
if [ "$TARGETARCH" = "amd64" ]; then \
|
||||
GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" CC=x86_64-linux-gnu-gcc go build -o /opt/bookmanager/server; \
|
||||
else \
|
||||
GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build -o /opt/bookmanager/server; \
|
||||
fi; \
|
||||
cp -a ./templates /opt/bookmanager/templates; \
|
||||
cp -a ./assets /opt/bookmanager/assets;
|
||||
|
||||
# Create Image
|
||||
FROM alpine:3.18
|
||||
FROM busybox:1.36
|
||||
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
|
||||
COPY --from=build /opt/bookmanager /opt/bookmanager
|
||||
WORKDIR /opt/bookmanager
|
||||
EXPOSE 8585
|
||||
|
8
Makefile
@ -14,9 +14,13 @@ docker_build_local:
|
||||
docker_build_release_beta:
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
-t gitea.va.reichard.io/reichard/bookmanager:beta --push .
|
||||
-t gitea.va.reichard.io/reichard/bookmanager:beta \
|
||||
-t gitea.va.reichard.io/evan/bookmanager:beta \
|
||||
--push .
|
||||
|
||||
docker_build_release_latest:
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
-t gitea.va.reichard.io/reichard/bookmanager:latest --push .
|
||||
-t gitea.va.reichard.io/reichard/bookmanager:latest \
|
||||
-t gitea.va.reichard.io/evan/bookmanager:latest \
|
||||
--push .
|
||||
|
51
README.md
@ -1,14 +1,20 @@
|
||||
# Book Manager
|
||||
|
||||
<p align="center">
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_login.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_login.png" width="30%">
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/login.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/login.png" width="18%">
|
||||
</a>
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_home.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_home.png" width="30%">
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/home.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/home.png" width="18%">
|
||||
</a>
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_documents.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/web_documents.png" width="30%">
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/documents.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/documents.png" width="18%">
|
||||
</a>
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/document.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/document.png" width="18%">
|
||||
</a>
|
||||
<a href="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/metadata.png">
|
||||
<img src="https://gitea.va.reichard.io/evan/BookManager/raw/branch/master/screenshots/pwa/metadata.png" width="18%">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -24,11 +30,30 @@ In additional to the compatible KOSync API's, we add:
|
||||
|
||||
- Additional APIs to automatically upload reading statistics
|
||||
- Automatically upload documents to the server (can download in the "Documents" view)
|
||||
- Automatic book cover metadata scraping (Thanks [OpenLibrary](https://openlibrary.org/))
|
||||
- Book metadata scraping (Thanks [OpenLibrary](https://openlibrary.org/) & [Google Books API](https://developers.google.com/books/docs/v1/getting_started))
|
||||
- No JavaScript! All information is rendered server side.
|
||||
|
||||
# Server
|
||||
|
||||
Docker Image: `docker pull gitea.va.reichard.io/evan/bookmanager:latest`
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Make Data Directory
|
||||
mkdir -p bookmanager_data
|
||||
|
||||
# Run Server
|
||||
docker run \
|
||||
-p 8585:8585 \
|
||||
-e REGISTRATION_ENABLED=true \
|
||||
-v ./bookmanager_data:/config \
|
||||
-v ./bookmanager_data:/data \
|
||||
gitea.va.reichard.io/evan/bookmanager:latest
|
||||
```
|
||||
|
||||
The service is now accessible at: `http://localhost:8585`
|
||||
|
||||
## Configuration
|
||||
|
||||
| Environment Variable | Default Value | Description |
|
||||
@ -50,22 +75,22 @@ See documentation in the `client` subfolder: [SyncNinja](https://gitea.va.reicha
|
||||
|
||||
SQLC Generation (v1.21.0):
|
||||
|
||||
```
|
||||
```bash
|
||||
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
|
||||
~/go/bin/sqlc generate
|
||||
```
|
||||
|
||||
Run Development:
|
||||
|
||||
```
|
||||
CONFIG_PATH=./data DATA_PATH=./data go run cmd/main.go serve
|
||||
```bash
|
||||
CONFIG_PATH=./data DATA_PATH=./data go run main.go serve
|
||||
```
|
||||
|
||||
# Building
|
||||
|
||||
The `Dockerfile` and `Makefile` contain the build information:
|
||||
|
||||
```
|
||||
```bash
|
||||
# Build Local Docker Image
|
||||
make docker_build_local
|
||||
|
||||
@ -75,12 +100,12 @@ make docker_build_release_latest
|
||||
|
||||
If manually building, you must enable CGO:
|
||||
|
||||
```
|
||||
```bash
|
||||
# Download Dependencies
|
||||
go mod download
|
||||
|
||||
# Compile (Binary `./bookmanager`)
|
||||
CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build -o /bookmanager cmd/main.go
|
||||
CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build -o /bookmanager
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
@ -21,8 +21,11 @@ type requestDocumentEdit struct {
|
||||
Title *string `form:"title"`
|
||||
Author *string `form:"author"`
|
||||
Description *string `form:"description"`
|
||||
ISBN10 *string `form:"isbn_10"`
|
||||
ISBN13 *string `form:"isbn_13"`
|
||||
RemoveCover *string `form:"remove_cover"`
|
||||
CoverFile *multipart.FileHeader `form:"cover"`
|
||||
CoverGBID *string `form:"cover_gbid"`
|
||||
CoverFile *multipart.FileHeader `form:"cover_file"`
|
||||
}
|
||||
|
||||
type requestDocumentIdentify struct {
|
||||
@ -101,6 +104,7 @@ func (api *API) createAppResourcesRoute(routeName string, args ...map[string]any
|
||||
return
|
||||
}
|
||||
|
||||
templateVars["RelBase"] = "../"
|
||||
templateVars["Data"] = document
|
||||
} else if routeName == "activity" {
|
||||
activityFilter := database.GetActivityParams{
|
||||
@ -131,7 +135,7 @@ func (api *API) createAppResourcesRoute(routeName string, args ...map[string]any
|
||||
if err != nil {
|
||||
log.Warn("[createAppResourcesRoute] GetUserWindowStreaks DB Error:", err)
|
||||
}
|
||||
log.Info("GetUserWindowStreaks - WEEK - ", time.Since(start_time))
|
||||
log.Debug("GetUserWindowStreaks - WEEK - ", time.Since(start_time))
|
||||
start_time = time.Now()
|
||||
|
||||
daily_streak, err := api.DB.Queries.GetUserWindowStreaks(api.DB.Ctx, database.GetUserWindowStreaksParams{
|
||||
@ -141,15 +145,15 @@ func (api *API) createAppResourcesRoute(routeName string, args ...map[string]any
|
||||
if err != nil {
|
||||
log.Warn("[createAppResourcesRoute] GetUserWindowStreaks DB Error:", err)
|
||||
}
|
||||
log.Info("GetUserWindowStreaks - DAY - ", time.Since(start_time))
|
||||
log.Debug("GetUserWindowStreaks - DAY - ", time.Since(start_time))
|
||||
|
||||
start_time = time.Now()
|
||||
database_info, _ := api.DB.Queries.GetDatabaseInfo(api.DB.Ctx, rUser.(string))
|
||||
log.Info("GetDatabaseInfo - ", time.Since(start_time))
|
||||
log.Debug("GetDatabaseInfo - ", time.Since(start_time))
|
||||
|
||||
start_time = time.Now()
|
||||
read_graph_data, _ := api.DB.Queries.GetDailyReadStats(api.DB.Ctx, rUser.(string))
|
||||
log.Info("GetDailyReadStats - ", time.Since(start_time))
|
||||
log.Debug("GetDailyReadStats - ", time.Since(start_time))
|
||||
|
||||
templateVars["Data"] = gin.H{
|
||||
"DailyStreak": daily_streak,
|
||||
@ -218,7 +222,7 @@ func (api *API) getDocumentCover(c *gin.Context) {
|
||||
firstResult := metadataResults[0]
|
||||
|
||||
// Save Cover
|
||||
fileName, err := metadata.SaveCover(*firstResult.GBID, coverDir, document.ID)
|
||||
fileName, err := metadata.SaveCover(*firstResult.GBID, coverDir, document.ID, false)
|
||||
if err == nil {
|
||||
coverFile = *fileName
|
||||
}
|
||||
@ -275,8 +279,11 @@ func (api *API) editDocument(c *gin.Context) {
|
||||
if rDocEdit.Author == nil &&
|
||||
rDocEdit.Title == nil &&
|
||||
rDocEdit.Description == nil &&
|
||||
rDocEdit.CoverFile == nil &&
|
||||
rDocEdit.RemoveCover == nil {
|
||||
rDocEdit.ISBN10 == nil &&
|
||||
rDocEdit.ISBN13 == nil &&
|
||||
rDocEdit.RemoveCover == nil &&
|
||||
rDocEdit.CoverGBID == nil &&
|
||||
rDocEdit.CoverFile == nil {
|
||||
log.Error("[createAppResourcesRoute] Missing Form Values")
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
@ -288,7 +295,6 @@ func (api *API) editDocument(c *gin.Context) {
|
||||
s := "UNKNOWN"
|
||||
coverFileName = &s
|
||||
} else if rDocEdit.CoverFile != nil {
|
||||
|
||||
// Validate Type & Derive Extension on MIME
|
||||
uploadedFile, err := rDocEdit.CoverFile.Open()
|
||||
if err != nil {
|
||||
@ -325,6 +331,14 @@ func (api *API) editDocument(c *gin.Context) {
|
||||
}
|
||||
|
||||
coverFileName = &fileName
|
||||
} else if rDocEdit.CoverGBID != nil {
|
||||
// TODO
|
||||
|
||||
var coverDir string = filepath.Join(api.Config.DataPath, "covers")
|
||||
fileName, err := metadata.SaveCover(*rDocEdit.CoverGBID, coverDir, rDocID.DocumentID, true)
|
||||
if err == nil {
|
||||
coverFileName = fileName
|
||||
}
|
||||
}
|
||||
|
||||
// Update Document
|
||||
@ -333,6 +347,8 @@ func (api *API) editDocument(c *gin.Context) {
|
||||
Title: api.sanitizeInput(rDocEdit.Title),
|
||||
Author: api.sanitizeInput(rDocEdit.Author),
|
||||
Description: api.sanitizeInput(rDocEdit.Description),
|
||||
Isbn10: api.sanitizeInput(rDocEdit.ISBN10),
|
||||
Isbn13: api.sanitizeInput(rDocEdit.ISBN13),
|
||||
Coverfile: coverFileName,
|
||||
}); err != nil {
|
||||
log.Error("[createAppResourcesRoute] UpsertDocument DB Error:", err)
|
||||
@ -367,6 +383,8 @@ func (api *API) deleteDocument(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (api *API) identifyDocument(c *gin.Context) {
|
||||
rUser, _ := c.Get("AuthorizedUser")
|
||||
|
||||
var rDocID requestDocumentID
|
||||
if err := c.ShouldBindUri(&rDocID); err != nil {
|
||||
log.Error("[identifyDocument] Invalid URI Bind")
|
||||
@ -399,36 +417,52 @@ func (api *API) identifyDocument(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Template Variables
|
||||
templateVars := gin.H{
|
||||
"RelBase": "../../",
|
||||
}
|
||||
|
||||
// Get Metadata
|
||||
metadataResults, err := metadata.GetMetadata(metadata.MetadataInfo{
|
||||
Title: rDocIdentify.Title,
|
||||
Author: rDocIdentify.Author,
|
||||
ISBN10: rDocIdentify.ISBN,
|
||||
ISBN13: rDocIdentify.ISBN,
|
||||
})
|
||||
if err != nil || len(metadataResults) == 0 {
|
||||
log.Error("[identifyDocument] Metadata Error")
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Metadata Error"})
|
||||
if err == nil && len(metadataResults) > 0 {
|
||||
firstResult := metadataResults[0]
|
||||
|
||||
// Store First Metadata Result
|
||||
if _, err = api.DB.Queries.AddMetadata(api.DB.Ctx, database.AddMetadataParams{
|
||||
DocumentID: rDocID.DocumentID,
|
||||
Title: firstResult.Title,
|
||||
Author: firstResult.Author,
|
||||
Description: firstResult.Description,
|
||||
Gbid: firstResult.GBID,
|
||||
Olid: firstResult.OLID,
|
||||
Isbn10: firstResult.ISBN10,
|
||||
Isbn13: firstResult.ISBN13,
|
||||
}); err != nil {
|
||||
log.Error("[identifyDocument] AddMetadata DB Error:", err)
|
||||
}
|
||||
|
||||
templateVars["Metadata"] = firstResult
|
||||
} else {
|
||||
log.Warn("[identifyDocument] Metadata Error")
|
||||
templateVars["MetadataError"] = "No Metadata Found"
|
||||
}
|
||||
|
||||
document, err := api.DB.Queries.GetDocumentWithStats(api.DB.Ctx, database.GetDocumentWithStatsParams{
|
||||
UserID: rUser.(string),
|
||||
DocumentID: rDocID.DocumentID,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("[identifyDocument] GetDocumentWithStats DB Error:", err)
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid Request"})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO
|
||||
firstResult := metadataResults[0]
|
||||
templateVars["Data"] = document
|
||||
|
||||
if firstResult.Title != nil {
|
||||
log.Info("Title:", *firstResult.Title)
|
||||
}
|
||||
if firstResult.Author != nil {
|
||||
log.Info("Author:", *firstResult.Author)
|
||||
}
|
||||
if firstResult.Description != nil {
|
||||
log.Info("Description:", *firstResult.Description)
|
||||
}
|
||||
if firstResult.ISBN10 != nil {
|
||||
log.Info("ISBN 10:", *firstResult.ISBN10)
|
||||
}
|
||||
if firstResult.ISBN13 != nil {
|
||||
log.Info("ISBN 13:", *firstResult.ISBN13)
|
||||
}
|
||||
|
||||
c.Redirect(http.StatusFound, "/")
|
||||
c.HTML(http.StatusOK, "document", templateVars)
|
||||
}
|
||||
|
@ -85,7 +85,8 @@ func (api *API) authFormLogin(c *gin.Context) {
|
||||
|
||||
if username == "" || rawPassword == "" {
|
||||
c.HTML(http.StatusUnauthorized, "login", gin.H{
|
||||
"Error": "Invalid Credentials",
|
||||
"RegistrationEnabled": api.Config.RegistrationEnabled,
|
||||
"Error": "Invalid Credentials",
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -93,7 +94,8 @@ func (api *API) authFormLogin(c *gin.Context) {
|
||||
|
||||
if authorized := api.authorizeCredentials(username, password); authorized != true {
|
||||
c.HTML(http.StatusUnauthorized, "login", gin.H{
|
||||
"Error": "Invalid Credentials",
|
||||
"RegistrationEnabled": api.Config.RegistrationEnabled,
|
||||
"Error": "Invalid Credentials",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -380,8 +380,12 @@ current_streak AS (
|
||||
end_date AS current_streak_end_date
|
||||
FROM streaks
|
||||
WHERE CASE
|
||||
WHEN ?2 = "WEEK" THEN DATE('now', time_offset, 'weekday 0', '-7 day') = current_streak_end_date
|
||||
WHEN ?2 = "DAY" THEN DATE('now', time_offset, '-1 day') = current_streak_end_date OR DATE('now', time_offset) = current_streak_end_date
|
||||
WHEN ?2 = "WEEK" THEN
|
||||
DATE('now', time_offset, 'weekday 0', '-14 day') = current_streak_end_date
|
||||
OR DATE('now', time_offset, 'weekday 0', '-7 day') = current_streak_end_date
|
||||
WHEN ?2 = "DAY" THEN
|
||||
DATE('now', time_offset, '-1 day') = current_streak_end_date
|
||||
OR DATE('now', time_offset) = current_streak_end_date
|
||||
END
|
||||
LIMIT 1
|
||||
)
|
||||
|
@ -1006,8 +1006,12 @@ current_streak AS (
|
||||
end_date AS current_streak_end_date
|
||||
FROM streaks
|
||||
WHERE CASE
|
||||
WHEN ?2 = "WEEK" THEN DATE('now', time_offset, 'weekday 0', '-7 day') = current_streak_end_date
|
||||
WHEN ?2 = "DAY" THEN DATE('now', time_offset, '-1 day') = current_streak_end_date OR DATE('now', time_offset) = current_streak_end_date
|
||||
WHEN ?2 = "WEEK" THEN
|
||||
DATE('now', time_offset, 'weekday 0', '-14 day') = current_streak_end_date
|
||||
OR DATE('now', time_offset, 'weekday 0', '-7 day') = current_streak_end_date
|
||||
WHEN ?2 = "DAY" THEN
|
||||
DATE('now', time_offset, '-1 day') = current_streak_end_date
|
||||
OR DATE('now', time_offset) = current_streak_end_date
|
||||
END
|
||||
LIMIT 1
|
||||
)
|
||||
|
@ -129,7 +129,7 @@ func GetMetadata(metadataSearch MetadataInfo) ([]MetadataInfo, error) {
|
||||
return allMetadata, nil
|
||||
}
|
||||
|
||||
func SaveCover(gbid string, coverDir string, documentID string) (*string, error) {
|
||||
func SaveCover(gbid string, coverDir string, documentID string, overwrite bool) (*string, error) {
|
||||
|
||||
// Google Books -> JPG
|
||||
coverFile := "." + filepath.Clean(fmt.Sprintf("/%s.jpg", documentID))
|
||||
@ -137,7 +137,7 @@ func SaveCover(gbid string, coverDir string, documentID string) (*string, error)
|
||||
|
||||
// Validate File Doesn't Exists
|
||||
_, err := os.Stat(coverFilePath)
|
||||
if err == nil {
|
||||
if err == nil && overwrite == false {
|
||||
log.Warn("[SaveCover] File Alreads Exists")
|
||||
return &coverFile, nil
|
||||
}
|
||||
|
11
screenshots/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Screenshots
|
||||
|
||||
## Process Images
|
||||
|
||||
```bash
|
||||
# Resize
|
||||
sips -Z 1500 *.png
|
||||
|
||||
# Crop Top & Bottom
|
||||
sips --cropOffset 85 1 -c 1385 693 *.png
|
||||
```
|
BIN
screenshots/pwa/activity.png
Normal file
After Width: | Height: | Size: 229 KiB |
BIN
screenshots/pwa/document.png
Normal file
After Width: | Height: | Size: 586 KiB |
BIN
screenshots/pwa/documents.png
Normal file
After Width: | Height: | Size: 490 KiB |
BIN
screenshots/pwa/home.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
screenshots/pwa/login.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
screenshots/pwa/metadata.png
Normal file
After Width: | Height: | Size: 335 KiB |
BIN
screenshots/pwa/navigation.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
screenshots/web/activity.png
Normal file
After Width: | Height: | Size: 245 KiB |
BIN
screenshots/web/document.png
Normal file
After Width: | Height: | Size: 639 KiB |
BIN
screenshots/web/documents.png
Normal file
After Width: | Height: | Size: 791 KiB |
BIN
screenshots/web/home.png
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
screenshots/web/login.png
Normal file
After Width: | Height: | Size: 790 KiB |
BIN
screenshots/web/metadata.png
Normal file
After Width: | Height: | Size: 357 KiB |
Before Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 362 KiB |
Before Width: | Height: | Size: 2.8 MiB |
@ -1,9 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="manifest" href="./manifest.json" />
|
||||
<link rel="manifest" href="{{ .RelBase }}./manifest.json" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=0.90, user-scalable=no">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<title>Book Manager - {{block "title" .}}{{end}}</title>
|
||||
</head>
|
||||
@ -11,215 +12,170 @@
|
||||
<main
|
||||
class="relative h-screen overflow-hidden bg-gray-100 dark:bg-gray-800"
|
||||
>
|
||||
<div class="flex items-start justify-between">
|
||||
<input type="checkbox" id="mobile-nav-button" class="hidden"/>
|
||||
<div class="fixed -left-64 duration-500 transition-all w-56 z-50 h-screen shadow-lg lg:left-0 lg:block lg:relative">
|
||||
<div class="h-full bg-white dark:bg-gray-700">
|
||||
<div class="flex items-center justify-center gap-4 h-16">
|
||||
<label
|
||||
id="mobile-nav-close-button"
|
||||
for="mobile-nav-button"
|
||||
class="flex block items-center p-2 text-gray-500 bg-white rounded-full shadow text-md cursor-pointer lg:hidden"
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
class="text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1664 1344v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45z"
|
||||
></path>
|
||||
</svg>
|
||||
</label>
|
||||
<p class="text-xl font-bold dark:text-white">Book Manager</p>
|
||||
<div class="flex items-center justify-between w-full h-16">
|
||||
<div id="mobile-nav-button" class="flex flex-col z-40 relative ml-6">
|
||||
<input type="checkbox" class="absolute lg:hidden z-50 -top-2 w-7 h-7 flex cursor-pointer opacity-0 w-12 h-12" />
|
||||
<span class="lg:hidden w-7 h-0.5 z-40 mt-0.5 bg-white"></span>
|
||||
<span class="lg:hidden w-7 h-0.5 z-40 mt-1 bg-white"></span>
|
||||
<span class="lg:hidden w-7 h-0.5 z-40 mt-1 bg-white"></span>
|
||||
|
||||
<div id="menu" class="fixed -mt-6 -ml-6 lg:-mt-8 h-full w-56 lg:w-48 bg-white dark:bg-gray-700 shadow-lg">
|
||||
<div class="h-16 flex justify-end lg:justify-around">
|
||||
<p class="text-xl font-bold dark:text-white text-right my-auto pr-4 lg:pr-0">Book Manager</p>
|
||||
</div>
|
||||
<nav class="mt-6">
|
||||
<div>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "home"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
<div class="mt-6">
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "home"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5192 7.82274C2 8.77128 2 9.91549 2 12.2039V13.725C2 17.6258 2 19.5763 3.17157 20.7881C4.34315 22 6.22876 22 10 22H14C17.7712 22 19.6569 22 20.8284 20.7881C22 19.5763 22 17.6258 22 13.725V12.2039C22 9.91549 22 8.77128 21.4808 7.82274C20.9616 6.87421 20.0131 6.28551 18.116 5.10812L16.116 3.86687C14.1106 2.62229 13.1079 2 12 2C10.8921 2 9.88939 2.62229 7.88403 3.86687L5.88403 5.10813C3.98695 6.28551 3.0384 6.87421 2.5192 7.82274ZM11.25 18C11.25 18.4142 11.5858 18.75 12 18.75C12.4142 18.75 12.75 18.4142 12.75 18V15C12.75 14.5858 12.4142 14.25 12 14.25C11.5858 14.25 11.25 14.5858 11.25 15V18Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Home </span>
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "documents"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/documents"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.27103 2.11151C5.46135 2.21816 5.03258 2.41324 4.72718 2.71244C4.42179 3.01165 4.22268 3.43172 4.11382 4.225C4.00176 5.04159 4 6.12387 4 7.67568V16.2442C4.38867 15.9781 4.82674 15.7756 5.29899 15.6517C5.82716 15.513 6.44305 15.5132 7.34563 15.5135L20 15.5135V7.67568C20 6.12387 19.9982 5.04159 19.8862 4.22499C19.7773 3.43172 19.5782 3.01165 19.2728 2.71244C18.9674 2.41324 18.5387 2.21816 17.729 2.11151C16.8955 2.00172 15.7908 2 14.2069 2H9.7931C8.2092 2 7.10452 2.00172 6.27103 2.11151ZM6.75862 6.59459C6.75862 6.1468 7.12914 5.78378 7.58621 5.78378H16.4138C16.8709 5.78378 17.2414 6.1468 17.2414 6.59459C17.2414 7.04239 16.8709 7.40541 16.4138 7.40541H7.58621C7.12914 7.40541 6.75862 7.04239 6.75862 6.59459ZM7.58621 9.56757C7.12914 9.56757 6.75862 9.93058 6.75862 10.3784C6.75862 10.8262 7.12914 11.1892 7.58621 11.1892H13.1034C13.5605 11.1892 13.931 10.8262 13.931 10.3784C13.931 9.93058 13.5605 9.56757 13.1034 9.56757H7.58621Z" />
|
||||
<path d="M7.47341 17.1351H8.68965H13.1034H19.9991C19.9956 18.2657 19.9776 19.1088 19.8862 19.775C19.7773 20.5683 19.5782 20.9884 19.2728 21.2876C18.9674 21.5868 18.5387 21.7818 17.729 21.8885C16.8955 21.9983 15.7908 22 14.2069 22H9.7931C8.2092 22 7.10452 21.9983 6.27103 21.8885C5.46135 21.7818 5.03258 21.5868 4.72718 21.2876C4.42179 20.9884 4.22268 20.5683 4.11382 19.775C4.07259 19.4746 4.0463 19.1382 4.02952 18.7558C4.30088 18.0044 4.93365 17.4264 5.72738 17.218C6.01657 17.1421 6.39395 17.1351 7.47341 17.1351Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Documents </span>
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "activity"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/activity"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M9.5 2C8.67157 2 8 2.67157 8 3.5V4.5C8 5.32843 8.67157 6 9.5 6H14.5C15.3284 6 16 5.32843 16 4.5V3.5C16 2.67157 15.3284 2 14.5 2H9.5Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 4.03662C5.24209 4.10719 4.44798 4.30764 3.87868 4.87694C3 5.75562 3 7.16983 3 9.99826V15.9983C3 18.8267 3 20.2409 3.87868 21.1196C4.75736 21.9983 6.17157 21.9983 9 21.9983H15C17.8284 21.9983 19.2426 21.9983 20.1213 21.1196C21 20.2409 21 18.8267 21 15.9983V9.99826C21 7.16983 21 5.75562 20.1213 4.87694C19.552 4.30764 18.7579 4.10719 17.5 4.03662V4.5C17.5 6.15685 16.1569 7.5 14.5 7.5H9.5C7.84315 7.5 6.5 6.15685 6.5 4.5V4.03662ZM7 9.75C6.58579 9.75 6.25 10.0858 6.25 10.5C6.25 10.9142 6.58579 11.25 7 11.25H7.5C7.91421 11.25 8.25 10.9142 8.25 10.5C8.25 10.0858 7.91421 9.75 7.5 9.75H7ZM10.5 9.75C10.0858 9.75 9.75 10.0858 9.75 10.5C9.75 10.9142 10.0858 11.25 10.5 11.25H17C17.4142 11.25 17.75 10.9142 17.75 10.5C17.75 10.0858 17.4142 9.75 17 9.75H10.5ZM7 13.25C6.58579 13.25 6.25 13.5858 6.25 14C6.25 14.4142 6.58579 14.75 7 14.75H7.5C7.91421 14.75 8.25 14.4142 8.25 14C8.25 13.5858 7.91421 13.25 7.5 13.25H7ZM10.5 13.25C10.0858 13.25 9.75 13.5858 9.75 14C9.75 14.4142 10.0858 14.75 10.5 14.75H17C17.4142 14.75 17.75 14.4142 17.75 14C17.75 13.5858 17.4142 13.25 17 13.25H10.5ZM7 16.75C6.58579 16.75 6.25 17.0858 6.25 17.5C6.25 17.9142 6.58579 18.25 7 18.25H7.5C7.91421 18.25 8.25 17.9142 8.25 17.5C8.25 17.0858 7.91421 16.75 7.5 16.75H7ZM10.5 16.75C10.0858 16.75 9.75 17.0858 9.75 17.5C9.75 17.9142 10.0858 18.25 10.5 18.25H17C17.4142 18.25 17.75 17.9142 17.75 17.5C17.75 17.0858 17.4142 16.75 17 16.75H10.5Z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Activity </span>
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "graphs"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/graphs"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355C22 19.0711 22 16.714 22 12C22 7.28595 22 4.92893 20.5355 3.46447C19.0711 2 16.714 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447ZM17.5762 10.4801C17.8413 10.1619 17.7983 9.68901 17.4801 9.42383C17.1619 9.15866 16.689 9.20165 16.4238 9.51986L14.6269 11.6761C14.2562 12.1211 14.0284 12.3915 13.8409 12.5609C13.7539 12.6394 13.7023 12.6708 13.6775 12.6827C13.6725 12.6852 13.6689 12.6866 13.6667 12.6875C13.6667 12.6875 13.6624 12.6858 13.659 12.6842L13.6558 12.6827C13.6311 12.6708 13.5795 12.6394 13.4925 12.5609C13.3049 12.3915 13.0772 12.1211 12.7064 11.6761L12.414 11.3252C12.0855 10.931 11.7894 10.5756 11.5128 10.3258C11.2119 10.0541 10.8328 9.81205 10.3333 9.81205C9.83384 9.81205 9.45478 10.0541 9.15384 10.3258C8.87725 10.5756 8.58113 10.931 8.25267 11.3253L6.42383 13.5199C6.15866 13.8381 6.20165 14.311 6.51986 14.5762C6.83807 14.8413 7.31099 14.7983 7.57617 14.4801L9.37306 12.3239C9.74385 11.8789 9.97155 11.6085 10.1591 11.4391C10.2461 11.3606 10.2977 11.3292 10.3225 11.3173C10.3251 11.316 10.3274 11.315 10.3292 11.3142L10.3333 11.3125C10.3356 11.3134 10.3392 11.3148 10.3442 11.3173C10.3689 11.3292 10.4205 11.3606 10.5075 11.4391C10.6951 11.6085 10.9228 11.8789 11.2936 12.3239L11.586 12.6748C11.9145 13.069 12.2106 13.4244 12.4872 13.6742C12.7881 13.9459 13.1672 14.188 13.6667 14.188C14.1662 14.188 14.5452 13.9459 14.8462 13.6742C15.1228 13.4244 15.4189 13.069 15.7473 12.6748L17.5762 10.4801Z"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5192 7.82274C2 8.77128 2 9.91549 2 12.2039V13.725C2 17.6258 2 19.5763 3.17157 20.7881C4.34315 22 6.22876 22 10 22H14C17.7712 22 19.6569 22 20.8284 20.7881C22 19.5763 22 17.6258 22 13.725V12.2039C22 9.91549 22 8.77128 21.4808 7.82274C20.9616 6.87421 20.0131 6.28551 18.116 5.10812L16.116 3.86687C14.1106 2.62229 13.1079 2 12 2C10.8921 2 9.88939 2.62229 7.88403 3.86687L5.88403 5.10813C3.98695 6.28551 3.0384 6.87421 2.5192 7.82274ZM11.25 18C11.25 18.4142 11.5858 18.75 12 18.75C12.4142 18.75 12.75 18.4142 12.75 18V15C12.75 14.5858 12.4142 14.25 12 14.25C11.5858 14.25 11.25 14.5858 11.25 15V18Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Home </span>
|
||||
</a>
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Graphs </span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="text-xl font-bold dark:text-white px-6">{{block "header" .}}{{end}}</h1>
|
||||
<div
|
||||
class="relative flex items-center justify-end w-full p-4 space-x-4"
|
||||
>
|
||||
<a href="#" class="relative block">
|
||||
<svg
|
||||
width="20"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
class="text-gray-800 dark:text-gray-200"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1523 1339q-22-155-87.5-257.5t-184.5-118.5q-67 74-159.5 115.5t-195.5 41.5-195.5-41.5-159.5-115.5q-119 16-184.5 118.5t-87.5 257.5q106 150 271 237.5t356 87.5 356-87.5 271-237.5zm-243-699q0-159-112.5-271.5t-271.5-112.5-271.5 112.5-112.5 271.5 112.5 271.5 271.5 112.5 271.5-112.5 112.5-271.5zm512 256q0 182-71 347.5t-190.5 286-285.5 191.5-349 71q-182 0-348-71t-286-191-191-286-71-348 71-348 191-286 286-191 348-71 348 71 286 191 191 286 71 348z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<input type="checkbox" id="user-dropdown-button" class="hidden"/>
|
||||
<div
|
||||
id="user-dropdown"
|
||||
class="transition duration-200 z-20 absolute right-4 top-16 pt-4"
|
||||
>
|
||||
<div
|
||||
class="w-56 origin-top-right bg-white rounded-md shadow-lg dark:shadow-gray-800 dark:bg-gray-700 ring-1 ring-black ring-opacity-5"
|
||||
>
|
||||
<div
|
||||
class="py-1"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="options-menu"
|
||||
>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "documents"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/documents"
|
||||
href="/logout"
|
||||
class="block block px-4 py-2 text-md text-gray-700 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-100 dark:hover:text-white dark:hover:bg-gray-600"
|
||||
role="menuitem"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.27103 2.11151C5.46135 2.21816 5.03258 2.41324 4.72718 2.71244C4.42179 3.01165 4.22268 3.43172 4.11382 4.225C4.00176 5.04159 4 6.12387 4 7.67568V16.2442C4.38867 15.9781 4.82674 15.7756 5.29899 15.6517C5.82716 15.513 6.44305 15.5132 7.34563 15.5135L20 15.5135V7.67568C20 6.12387 19.9982 5.04159 19.8862 4.22499C19.7773 3.43172 19.5782 3.01165 19.2728 2.71244C18.9674 2.41324 18.5387 2.21816 17.729 2.11151C16.8955 2.00172 15.7908 2 14.2069 2H9.7931C8.2092 2 7.10452 2.00172 6.27103 2.11151ZM6.75862 6.59459C6.75862 6.1468 7.12914 5.78378 7.58621 5.78378H16.4138C16.8709 5.78378 17.2414 6.1468 17.2414 6.59459C17.2414 7.04239 16.8709 7.40541 16.4138 7.40541H7.58621C7.12914 7.40541 6.75862 7.04239 6.75862 6.59459ZM7.58621 9.56757C7.12914 9.56757 6.75862 9.93058 6.75862 10.3784C6.75862 10.8262 7.12914 11.1892 7.58621 11.1892H13.1034C13.5605 11.1892 13.931 10.8262 13.931 10.3784C13.931 9.93058 13.5605 9.56757 13.1034 9.56757H7.58621Z" />
|
||||
<path d="M7.47341 17.1351H8.68965H13.1034H19.9991C19.9956 18.2657 19.9776 19.1088 19.8862 19.775C19.7773 20.5683 19.5782 20.9884 19.2728 21.2876C18.9674 21.5868 18.5387 21.7818 17.729 21.8885C16.8955 21.9983 15.7908 22 14.2069 22H9.7931C8.2092 22 7.10452 21.9983 6.27103 21.8885C5.46135 21.7818 5.03258 21.5868 4.72718 21.2876C4.42179 20.9884 4.22268 20.5683 4.11382 19.775C4.07259 19.4746 4.0463 19.1382 4.02952 18.7558C4.30088 18.0044 4.93365 17.4264 5.72738 17.218C6.01657 17.1421 6.39395 17.1351 7.47341 17.1351Z" />
|
||||
</svg>
|
||||
<span class="flex flex-col">
|
||||
<span>Logout</span>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Documents </span>
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "activity"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/activity"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M9.5 2C8.67157 2 8 2.67157 8 3.5V4.5C8 5.32843 8.67157 6 9.5 6H14.5C15.3284 6 16 5.32843 16 4.5V3.5C16 2.67157 15.3284 2 14.5 2H9.5Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 4.03662C5.24209 4.10719 4.44798 4.30764 3.87868 4.87694C3 5.75562 3 7.16983 3 9.99826V15.9983C3 18.8267 3 20.2409 3.87868 21.1196C4.75736 21.9983 6.17157 21.9983 9 21.9983H15C17.8284 21.9983 19.2426 21.9983 20.1213 21.1196C21 20.2409 21 18.8267 21 15.9983V9.99826C21 7.16983 21 5.75562 20.1213 4.87694C19.552 4.30764 18.7579 4.10719 17.5 4.03662V4.5C17.5 6.15685 16.1569 7.5 14.5 7.5H9.5C7.84315 7.5 6.5 6.15685 6.5 4.5V4.03662ZM7 9.75C6.58579 9.75 6.25 10.0858 6.25 10.5C6.25 10.9142 6.58579 11.25 7 11.25H7.5C7.91421 11.25 8.25 10.9142 8.25 10.5C8.25 10.0858 7.91421 9.75 7.5 9.75H7ZM10.5 9.75C10.0858 9.75 9.75 10.0858 9.75 10.5C9.75 10.9142 10.0858 11.25 10.5 11.25H17C17.4142 11.25 17.75 10.9142 17.75 10.5C17.75 10.0858 17.4142 9.75 17 9.75H10.5ZM7 13.25C6.58579 13.25 6.25 13.5858 6.25 14C6.25 14.4142 6.58579 14.75 7 14.75H7.5C7.91421 14.75 8.25 14.4142 8.25 14C8.25 13.5858 7.91421 13.25 7.5 13.25H7ZM10.5 13.25C10.0858 13.25 9.75 13.5858 9.75 14C9.75 14.4142 10.0858 14.75 10.5 14.75H17C17.4142 14.75 17.75 14.4142 17.75 14C17.75 13.5858 17.4142 13.25 17 13.25H10.5ZM7 16.75C6.58579 16.75 6.25 17.0858 6.25 17.5C6.25 17.9142 6.58579 18.25 7 18.25H7.5C7.91421 18.25 8.25 17.9142 8.25 17.5C8.25 17.0858 7.91421 16.75 7.5 16.75H7ZM10.5 16.75C10.0858 16.75 9.75 17.0858 9.75 17.5C9.75 17.9142 10.0858 18.25 10.5 18.25H17C17.4142 18.25 17.75 17.9142 17.75 17.5C17.75 17.0858 17.4142 16.75 17 16.75H10.5Z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Activity </span>
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center justify-start w-full p-2 pl-6 my-2 transition-colors duration-200 border-l-4 {{if eq .RouteName "graphs"}}border-purple-500 dark:text-white{{else}}border-transparent text-gray-400 hover:text-gray-800 dark:hover:text-gray-100{{end}}"
|
||||
href="/graphs"
|
||||
>
|
||||
<span class="text-left">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355C22 19.0711 22 16.714 22 12C22 7.28595 22 4.92893 20.5355 3.46447C19.0711 2 16.714 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447ZM17.5762 10.4801C17.8413 10.1619 17.7983 9.68901 17.4801 9.42383C17.1619 9.15866 16.689 9.20165 16.4238 9.51986L14.6269 11.6761C14.2562 12.1211 14.0284 12.3915 13.8409 12.5609C13.7539 12.6394 13.7023 12.6708 13.6775 12.6827C13.6725 12.6852 13.6689 12.6866 13.6667 12.6875C13.6667 12.6875 13.6624 12.6858 13.659 12.6842L13.6558 12.6827C13.6311 12.6708 13.5795 12.6394 13.4925 12.5609C13.3049 12.3915 13.0772 12.1211 12.7064 11.6761L12.414 11.3252C12.0855 10.931 11.7894 10.5756 11.5128 10.3258C11.2119 10.0541 10.8328 9.81205 10.3333 9.81205C9.83384 9.81205 9.45478 10.0541 9.15384 10.3258C8.87725 10.5756 8.58113 10.931 8.25267 11.3253L6.42383 13.5199C6.15866 13.8381 6.20165 14.311 6.51986 14.5762C6.83807 14.8413 7.31099 14.7983 7.57617 14.4801L9.37306 12.3239C9.74385 11.8789 9.97155 11.6085 10.1591 11.4391C10.2461 11.3606 10.2977 11.3292 10.3225 11.3173C10.3251 11.316 10.3274 11.315 10.3292 11.3142L10.3333 11.3125C10.3356 11.3134 10.3392 11.3148 10.3442 11.3173C10.3689 11.3292 10.4205 11.3606 10.5075 11.4391C10.6951 11.6085 10.9228 11.8789 11.2936 12.3239L11.586 12.6748C11.9145 13.069 12.2106 13.4244 12.4872 13.6742C12.7881 13.9459 13.1672 14.188 13.6667 14.188C14.1662 14.188 14.5452 13.9459 14.8462 13.6742C15.1228 13.4244 15.4189 13.069 15.7473 12.6748L17.5762 10.4801Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="mx-4 text-sm font-normal"> Graphs </span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-full">
|
||||
<header class="z-40 flex items-center justify-between w-full h-16">
|
||||
<div class="block ml-6 lg:hidden">
|
||||
<label
|
||||
for="mobile-nav-button"
|
||||
class="flex items-center p-2 text-gray-500 bg-white rounded-full shadow text-md cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
class="text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1664 1344v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45zm0-512v128q0 26-19 45t-45 19h-1408q-26 0-45-19t-19-45v-128q0-26 19-45t45-19h1408q26 0 45 19t19 45z"
|
||||
></path>
|
||||
</svg>
|
||||
</label>
|
||||
</div>
|
||||
<h1 class="text-xl font-bold dark:text-white px-6">{{block "header" .}}{{end}}</h1>
|
||||
<div
|
||||
class="relative flex items-center justify-end w-full p-4 space-x-4"
|
||||
>
|
||||
<a href="#" class="relative block">
|
||||
<svg
|
||||
width="20"
|
||||
fill="currentColor"
|
||||
height="20"
|
||||
class="text-gray-800 dark:text-gray-200"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1523 1339q-22-155-87.5-257.5t-184.5-118.5q-67 74-159.5 115.5t-195.5 41.5-195.5-41.5-159.5-115.5q-119 16-184.5 118.5t-87.5 257.5q106 150 271 237.5t356 87.5 356-87.5 271-237.5zm-243-699q0-159-112.5-271.5t-271.5-112.5-271.5 112.5-112.5 271.5 112.5 271.5 271.5 112.5 271.5-112.5 112.5-271.5zm512 256q0 182-71 347.5t-190.5 286-285.5 191.5-349 71q-182 0-348-71t-286-191-191-286-71-348 71-348 191-286 286-191 348-71 348 71 286 191 191 286 71 348z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<input type="checkbox" id="user-dropdown-button" class="hidden"/>
|
||||
<div
|
||||
id="user-dropdown"
|
||||
class="transition duration-200 absolute right-4 top-16 pt-4"
|
||||
>
|
||||
<div
|
||||
class="w-56 origin-top-right bg-white rounded-md shadow-lg dark:shadow-gray-800 dark:bg-gray-700 ring-1 ring-black ring-opacity-5"
|
||||
>
|
||||
<div
|
||||
class="py-1"
|
||||
role="menu"
|
||||
aria-orientation="vertical"
|
||||
aria-labelledby="options-menu"
|
||||
>
|
||||
<a
|
||||
href="/logout"
|
||||
class="block block px-4 py-2 text-md text-gray-700 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-100 dark:hover:text-white dark:hover:bg-gray-600"
|
||||
role="menuitem"
|
||||
>
|
||||
<span class="flex flex-col">
|
||||
<span>Logout</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label for="user-dropdown-button">
|
||||
<div
|
||||
class="flex items-center text-gray-500 dark:text-white text-md py-4 cursor-pointer"
|
||||
>
|
||||
{{ .User }}
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
class="ml-2 text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<div class="h-screen px-4 pb-24 overflow-auto md:px-6">
|
||||
{{block "content" .}}{{end}}
|
||||
</div>
|
||||
<label for="user-dropdown-button">
|
||||
<div
|
||||
class="flex items-center text-gray-500 dark:text-white text-md py-4 cursor-pointer"
|
||||
>
|
||||
{{ .User }}
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
class="ml-2 text-gray-400"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 1792 1792"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-screen px-4 pb-24 overflow-auto md:px-6 lg:ml-48">
|
||||
{{block "content" .}}{{end}}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Custom Animation CSS -->
|
||||
<style>
|
||||
|
||||
/* ----------------------------- */
|
||||
/* ------ Navigation Slide ----- */
|
||||
/* ----------------------------- */
|
||||
#mobile-nav-button:checked + div {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
/* ----------------------------- */
|
||||
/* ------- User Dropdown ------- */
|
||||
/* ----------------------------- */
|
||||
@ -229,8 +185,57 @@
|
||||
}
|
||||
|
||||
#user-dropdown {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* ----------------------------- */
|
||||
/* ----- Mobile Navigation ----- */
|
||||
/* ----------------------------- */
|
||||
#mobile-nav-button span {
|
||||
transform-origin: 5px 0px;
|
||||
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
|
||||
background 0.5s cubic-bezier(0.77,0.2,0.05,1.0),
|
||||
opacity 0.55s ease;
|
||||
}
|
||||
|
||||
#mobile-nav-button span:first-child {
|
||||
transform-origin: 0% 0%;
|
||||
}
|
||||
|
||||
#mobile-nav-button span:nth-last-child(2) {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
#mobile-nav-button input:checked ~ span {
|
||||
opacity: 1;
|
||||
transform: rotate(45deg) translate(2px, -2px);
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
#mobile-nav-button input:checked ~ span:nth-last-child(3) {
|
||||
opacity: 0;
|
||||
transform: rotate(0deg) scale(0.2, 0.2);
|
||||
}
|
||||
|
||||
#mobile-nav-button input:checked ~ span:nth-last-child(2) {
|
||||
transform: rotate(-45deg) translate(0, 6px);
|
||||
}
|
||||
|
||||
#mobile-nav-button input:checked ~ div {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
#mobile-nav-button input ~ div {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
#menu {
|
||||
transform-origin: 0% 0%;
|
||||
transform: translate(-100%, 0);
|
||||
transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0);
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
|
@ -1,106 +1,172 @@
|
||||
{{template "base.html" .}}
|
||||
{{template "base.html" . }}
|
||||
|
||||
{{define "title"}}Documents{{end}}
|
||||
|
||||
{{define "header"}}
|
||||
<a href="../documents">Documents</a>
|
||||
<a href="{{ .RelBase }}./documents">Documents</a>
|
||||
{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="h-full w-full overflow-scroll bg-white shadow-lg dark:bg-gray-700 rounded dark:text-white p-4">
|
||||
<div class="flex flex-col gap-2 float-left w-40 md:w-60 lg:w-80 mr-4 mb-2 relative">
|
||||
<label class="z-20 cursor-pointer" for="edit-cover-button">
|
||||
<img class="rounded object-fill h-full" src="../documents/{{.Data.ID}}/cover"></img>
|
||||
</label>
|
||||
<div class="flex flex-wrap-reverse justify-between z-40 gap-2 relative">
|
||||
<div class="mr-2 min-w-[50%]">
|
||||
<div class="flex gap-1 text-sm">
|
||||
<p class="text-gray-400">ISBN 10:</p>
|
||||
<p class="font-medium">
|
||||
{{ or .Data.Isbn10 "N/A" }}
|
||||
</p>
|
||||
<div class="h-full w-full relative">
|
||||
<!-- Document Info -->
|
||||
<div class="h-full w-full overflow-scroll bg-white shadow-lg dark:bg-gray-700 rounded dark:text-white p-4">
|
||||
<div class="flex flex-col gap-2 float-left w-44 md:w-60 lg:w-80 mr-4 mb-2 relative">
|
||||
<label class="z-10 cursor-pointer" for="edit-cover-button">
|
||||
<img class="rounded object-fill w-full" src="{{ .RelBase }}./documents/{{.Data.ID}}/cover"></img>
|
||||
</label>
|
||||
<div class="flex flex-wrap-reverse justify-between z-20 gap-2 relative">
|
||||
<div class="min-w-[50%] md:mr-2">
|
||||
<div class="flex gap-1 text-sm">
|
||||
<p class="text-gray-500">ISBN-10:</p>
|
||||
<p class="font-medium">
|
||||
{{ or .Data.Isbn10 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-1 text-sm">
|
||||
<p class="text-gray-500">ISBN-13:</p>
|
||||
<p class="font-medium">
|
||||
{{ or .Data.Isbn13 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-1 text-sm">
|
||||
<p class="text-gray-400">ISBN 13:</p>
|
||||
<p class="font-medium">
|
||||
{{ or .Data.Isbn13 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex grow justify-between my-auto text-gray-500 dark:text-gray-400">
|
||||
<input type="checkbox" id="edit-cover-button" class="hidden css-button"/>
|
||||
<div class="absolute z-50 flex flex-col gap-2 top-0 left-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
enctype="multipart/form-data"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-72 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
id="cover"
|
||||
name="cover"
|
||||
<div class="flex grow justify-between my-auto text-gray-500 dark:text-gray-500">
|
||||
<input type="checkbox" id="edit-cover-button" class="hidden css-button"/>
|
||||
<div class="absolute z-30 flex flex-col gap-2 top-0 left-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
enctype="multipart/form-data"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-72 text-black dark:text-white text-sm"
|
||||
>
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Upload Cover</button>
|
||||
</form>
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-72 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input type="checkbox" checked id="remove_cover" name="remove_cover" class="hidden" />
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Remove Cover</button>
|
||||
</form>
|
||||
<input
|
||||
type="file"
|
||||
id="cover_file"
|
||||
name="cover_file"
|
||||
>
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Upload Cover</button>
|
||||
</form>
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-72 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input type="checkbox" checked id="remove_cover" name="remove_cover" class="hidden" />
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Remove Cover</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="relative">
|
||||
<label for="delete-button">
|
||||
</div>
|
||||
<div class="relative">
|
||||
<label for="delete-button">
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 6.52381C3 6.12932 3.32671 5.80952 3.72973 5.80952H8.51787C8.52437 4.9683 8.61554 3.81504 9.45037 3.01668C10.1074 2.38839 11.0081 2 12 2C12.9919 2 13.8926 2.38839 14.5496 3.01668C15.3844 3.81504 15.4756 4.9683 15.4821 5.80952H20.2703C20.6733 5.80952 21 6.12932 21 6.52381C21 6.9183 20.6733 7.2381 20.2703 7.2381H3.72973C3.32671 7.2381 3 6.9183 3 6.52381Z"
|
||||
/>
|
||||
<path
|
||||
d="M11.6066 22H12.3935C15.101 22 16.4547 22 17.3349 21.1368C18.2151 20.2736 18.3052 18.8576 18.4853 16.0257L18.7448 11.9452C18.8425 10.4086 18.8913 9.64037 18.4498 9.15352C18.0082 8.66667 17.2625 8.66667 15.7712 8.66667H8.22884C6.7375 8.66667 5.99183 8.66667 5.55026 9.15352C5.1087 9.64037 5.15756 10.4086 5.25528 11.9452L5.51479 16.0257C5.69489 18.8576 5.78494 20.2736 6.66513 21.1368C7.54532 22 8.89906 22 11.6066 22Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="delete-button" class="hidden css-button"/>
|
||||
<div class="absolute z-30 bottom-7 left-5 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/delete"
|
||||
class="text-black dark:text-white text-sm"
|
||||
>
|
||||
<button
|
||||
class="font-medium w-24 px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<a href="../activity?document={{ .Data.ID }}">
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
class="hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3 6.52381C3 6.12932 3.32671 5.80952 3.72973 5.80952H8.51787C8.52437 4.9683 8.61554 3.81504 9.45037 3.01668C10.1074 2.38839 11.0081 2 12 2C12.9919 2 13.8926 2.38839 14.5496 3.01668C15.3844 3.81504 15.4756 4.9683 15.4821 5.80952H20.2703C20.6733 5.80952 21 6.12932 21 6.52381C21 6.9183 20.6733 7.2381 20.2703 7.2381H3.72973C3.32671 7.2381 3 6.9183 3 6.52381Z"
|
||||
/>
|
||||
<path
|
||||
d="M11.6066 22H12.3935C15.101 22 16.4547 22 17.3349 21.1368C18.2151 20.2736 18.3052 18.8576 18.4853 16.0257L18.7448 11.9452C18.8425 10.4086 18.8913 9.64037 18.4498 9.15352C18.0082 8.66667 17.2625 8.66667 15.7712 8.66667H8.22884C6.7375 8.66667 5.99183 8.66667 5.55026 9.15352C5.1087 9.64037 5.15756 10.4086 5.25528 11.9452L5.51479 16.0257C5.69489 18.8576 5.78494 20.2736 6.66513 21.1368C7.54532 22 8.89906 22 11.6066 22Z"
|
||||
/>
|
||||
<path d="M9.5 2C8.67157 2 8 2.67157 8 3.5V4.5C8 5.32843 8.67157 6 9.5 6H14.5C15.3284 6 16 5.32843 16 4.5V3.5C16 2.67157 15.3284 2 14.5 2H9.5Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 4.03662C5.24209 4.10719 4.44798 4.30764 3.87868 4.87694C3 5.75562 3 7.16983 3 9.99826V15.9983C3 18.8267 3 20.2409 3.87868 21.1196C4.75736 21.9983 6.17157 21.9983 9 21.9983H15C17.8284 21.9983 19.2426 21.9983 20.1213 21.1196C21 20.2409 21 18.8267 21 15.9983V9.99826C21 7.16983 21 5.75562 20.1213 4.87694C19.552 4.30764 18.7579 4.10719 17.5 4.03662V4.5C17.5 6.15685 16.1569 7.5 14.5 7.5H9.5C7.84315 7.5 6.5 6.15685 6.5 4.5V4.03662ZM7 9.75C6.58579 9.75 6.25 10.0858 6.25 10.5C6.25 10.9142 6.58579 11.25 7 11.25H7.5C7.91421 11.25 8.25 10.9142 8.25 10.5C8.25 10.0858 7.91421 9.75 7.5 9.75H7ZM10.5 9.75C10.0858 9.75 9.75 10.0858 9.75 10.5C9.75 10.9142 10.0858 11.25 10.5 11.25H17C17.4142 11.25 17.75 10.9142 17.75 10.5C17.75 10.0858 17.4142 9.75 17 9.75H10.5ZM7 13.25C6.58579 13.25 6.25 13.5858 6.25 14C6.25 14.4142 6.58579 14.75 7 14.75H7.5C7.91421 14.75 8.25 14.4142 8.25 14C8.25 13.5858 7.91421 13.25 7.5 13.25H7ZM10.5 13.25C10.0858 13.25 9.75 13.5858 9.75 14C9.75 14.4142 10.0858 14.75 10.5 14.75H17C17.4142 14.75 17.75 14.4142 17.75 14C17.75 13.5858 17.4142 13.25 17 13.25H10.5ZM7 16.75C6.58579 16.75 6.25 17.0858 6.25 17.5C6.25 17.9142 6.58579 18.25 7 18.25H7.5C7.91421 18.25 8.25 17.9142 8.25 17.5C8.25 17.0858 7.91421 16.75 7.5 16.75H7ZM10.5 16.75C10.0858 16.75 9.75 17.0858 9.75 17.5C9.75 17.9142 10.0858 18.25 10.5 18.25H17C17.4142 18.25 17.75 17.9142 17.75 17.5C17.75 17.0858 17.4142 16.75 17 16.75H10.5Z"/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="delete-button" class="hidden css-button"/>
|
||||
<div class="absolute z-50 bottom-7 left-5 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/delete"
|
||||
class="text-black dark:text-white text-sm"
|
||||
>
|
||||
<button class="font-medium w-24 px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Delete</button>
|
||||
</form>
|
||||
</a>
|
||||
<div class="relative">
|
||||
<label for="edit-button">
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12ZM9 11.5C9 10.1193 10.1193 9 11.5 9C12.8807 9 14 10.1193 14 11.5C14 12.8807 12.8807 14 11.5 14C10.1193 14 9 12.8807 9 11.5ZM11.5 7C9.01472 7 7 9.01472 7 11.5C7 13.9853 9.01472 16 11.5 16C12.3805 16 13.202 15.7471 13.8957 15.31L15.2929 16.7071C15.6834 17.0976 16.3166 17.0976 16.7071 16.7071C17.0976 16.3166 17.0976 15.6834 16.7071 15.2929L15.31 13.8957C15.7471 13.202 16 12.3805 16 11.5C16 9.01472 13.9853 7 11.5 7Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-button" class="hidden css-button"/>
|
||||
<div class="absolute z-30 bottom-7 left-5 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/identify"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
placeholder="Title"
|
||||
value="{{ or .Data.Title nil }}"
|
||||
class="p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="author"
|
||||
name="author"
|
||||
placeholder="Author"
|
||||
value="{{ or .Data.Author nil }}"
|
||||
class="p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="isbn"
|
||||
name="isbn"
|
||||
placeholder="ISBN 10 / ISBN 13"
|
||||
value="{{ or .Data.Isbn13 (or .Data.Isbn10 nil) }}"
|
||||
class="p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Identify</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="../activity?document={{ .Data.ID }}">
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M9.5 2C8.67157 2 8 2.67157 8 3.5V4.5C8 5.32843 8.67157 6 9.5 6H14.5C15.3284 6 16 5.32843 16 4.5V3.5C16 2.67157 15.3284 2 14.5 2H9.5Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 4.03662C5.24209 4.10719 4.44798 4.30764 3.87868 4.87694C3 5.75562 3 7.16983 3 9.99826V15.9983C3 18.8267 3 20.2409 3.87868 21.1196C4.75736 21.9983 6.17157 21.9983 9 21.9983H15C17.8284 21.9983 19.2426 21.9983 20.1213 21.1196C21 20.2409 21 18.8267 21 15.9983V9.99826C21 7.16983 21 5.75562 20.1213 4.87694C19.552 4.30764 18.7579 4.10719 17.5 4.03662V4.5C17.5 6.15685 16.1569 7.5 14.5 7.5H9.5C7.84315 7.5 6.5 6.15685 6.5 4.5V4.03662ZM7 9.75C6.58579 9.75 6.25 10.0858 6.25 10.5C6.25 10.9142 6.58579 11.25 7 11.25H7.5C7.91421 11.25 8.25 10.9142 8.25 10.5C8.25 10.0858 7.91421 9.75 7.5 9.75H7ZM10.5 9.75C10.0858 9.75 9.75 10.0858 9.75 10.5C9.75 10.9142 10.0858 11.25 10.5 11.25H17C17.4142 11.25 17.75 10.9142 17.75 10.5C17.75 10.0858 17.4142 9.75 17 9.75H10.5ZM7 13.25C6.58579 13.25 6.25 13.5858 6.25 14C6.25 14.4142 6.58579 14.75 7 14.75H7.5C7.91421 14.75 8.25 14.4142 8.25 14C8.25 13.5858 7.91421 13.25 7.5 13.25H7ZM10.5 13.25C10.0858 13.25 9.75 13.5858 9.75 14C9.75 14.4142 10.0858 14.75 10.5 14.75H17C17.4142 14.75 17.75 14.4142 17.75 14C17.75 13.5858 17.4142 13.25 17 13.25H10.5ZM7 16.75C6.58579 16.75 6.25 17.0858 6.25 17.5C6.25 17.9142 6.58579 18.25 7 18.25H7.5C7.91421 18.25 8.25 17.9142 8.25 17.5C8.25 17.0858 7.91421 16.75 7.5 16.75H7ZM10.5 16.75C10.0858 16.75 9.75 17.0858 9.75 17.5C9.75 17.9142 10.0858 18.25 10.5 18.25H17C17.4142 18.25 17.75 17.9142 17.75 17.5C17.75 17.0858 17.4142 16.75 17 16.75H10.5Z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<div class="relative">
|
||||
<label for="edit-button">
|
||||
{{ if .Data.Filepath }}
|
||||
<a href="./{{.Data.ID}}/file">
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
class="hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -108,48 +174,15 @@
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12ZM9 11.5C9 10.1193 10.1193 9 11.5 9C12.8807 9 14 10.1193 14 11.5C14 12.8807 12.8807 14 11.5 14C10.1193 14 9 12.8807 9 11.5ZM11.5 7C9.01472 7 7 9.01472 7 11.5C7 13.9853 9.01472 16 11.5 16C12.3805 16 13.202 15.7471 13.8957 15.31L15.2929 16.7071C15.6834 17.0976 16.3166 17.0976 16.7071 16.7071C17.0976 16.3166 17.0976 15.6834 16.7071 15.2929L15.31 13.8957C15.7471 13.202 16 12.3805 16 11.5C16 9.01472 13.9853 7 11.5 7Z"
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V12.1893L14.4697 10.4697C14.7626 10.1768 15.2374 10.1768 15.5303 10.4697C15.8232 10.7626 15.8232 11.2374 15.5303 11.5303L12.5303 14.5303C12.3897 14.671 12.1989 14.75 12 14.75C11.8011 14.75 11.6103 14.671 11.4697 14.5303L8.46967 11.5303C8.17678 11.2374 8.17678 10.7626 8.46967 10.4697C8.76256 10.1768 9.23744 10.1768 9.53033 10.4697L11.25 12.1893V7C11.25 6.58579 11.5858 6.25 12 6.25ZM8 16.25C7.58579 16.25 7.25 16.5858 7.25 17C7.25 17.4142 7.58579 17.75 8 17.75H16C16.4142 17.75 16.75 17.4142 16.75 17C16.75 16.5858 16.4142 16.25 16 16.25H8Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-button" class="hidden css-button"/>
|
||||
<div class="absolute z-50 bottom-7 left-5 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/identify"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
placeholder="Title"
|
||||
class="p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="author"
|
||||
name="author"
|
||||
placeholder="Author"
|
||||
class="p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="isbn"
|
||||
name="isbn"
|
||||
placeholder="ISBN 10 / ISBN 13"
|
||||
class="p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Identify</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .Data.Filepath }}
|
||||
<a href="./{{.Data.ID}}/file">
|
||||
</a>
|
||||
{{ else }}
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="hover:text-gray-800 dark:hover:text-gray-100"
|
||||
class="text-gray-200 dark:text-gray-600"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -160,31 +193,140 @@
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V12.1893L14.4697 10.4697C14.7626 10.1768 15.2374 10.1768 15.5303 10.4697C15.8232 10.7626 15.8232 11.2374 15.5303 11.5303L12.5303 14.5303C12.3897 14.671 12.1989 14.75 12 14.75C11.8011 14.75 11.6103 14.671 11.4697 14.5303L8.46967 11.5303C8.17678 11.2374 8.17678 10.7626 8.46967 10.4697C8.76256 10.1768 9.23744 10.1768 9.53033 10.4697L11.25 12.1893V7C11.25 6.58579 11.5858 6.25 12 6.25ZM8 16.25C7.58579 16.25 7.25 16.5858 7.25 17C7.25 17.4142 7.58579 17.75 8 17.75H16C16.4142 17.75 16.75 17.4142 16.75 17C16.75 16.5858 16.4142 16.25 16 16.25H8Z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
{{ else }}
|
||||
<svg
|
||||
width="28"
|
||||
height="28"
|
||||
class="text-gray-200 dark:text-gray-600"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12ZM12 6.25C12.4142 6.25 12.75 6.58579 12.75 7V12.1893L14.4697 10.4697C14.7626 10.1768 15.2374 10.1768 15.5303 10.4697C15.8232 10.7626 15.8232 11.2374 15.5303 11.5303L12.5303 14.5303C12.3897 14.671 12.1989 14.75 12 14.75C11.8011 14.75 11.6103 14.671 11.4697 14.5303L8.46967 11.5303C8.17678 11.2374 8.17678 10.7626 8.46967 10.4697C8.76256 10.1768 9.23744 10.1768 9.53033 10.4697L11.25 12.1893V7C11.25 6.58579 11.5858 6.25 12 6.25ZM8 16.25C7.58579 16.25 7.25 16.5858 7.25 17C7.25 17.4142 7.58579 17.75 8 17.75H16C16.4142 17.75 16.75 17.4142 16.75 17C16.75 16.5858 16.4142 16.25 16 16.25H8Z"
|
||||
/>
|
||||
</svg>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 justify-between gap-4 pb-4">
|
||||
<div class="grid sm:grid-cols-2 justify-between gap-4 pb-4">
|
||||
<div class="relative">
|
||||
<div class="text-gray-500 inline-flex gap-2 relative">
|
||||
<p>Title</p>
|
||||
<label class="my-auto" for="edit-title-button">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21.1938 2.80624C22.2687 3.88124 22.2687 5.62415 21.1938 6.69914L20.6982 7.19469C20.5539 7.16345 20.3722 7.11589 20.1651 7.04404C19.6108 6.85172 18.8823 6.48827 18.197 5.803C17.5117 5.11774 17.1483 4.38923 16.956 3.8349C16.8841 3.62781 16.8366 3.44609 16.8053 3.30179L17.3009 2.80624C18.3759 1.73125 20.1188 1.73125 21.1938 2.80624Z"
|
||||
/>
|
||||
<path
|
||||
d="M14.5801 13.3128C14.1761 13.7168 13.9741 13.9188 13.7513 14.0926C13.4886 14.2975 13.2043 14.4732 12.9035 14.6166C12.6485 14.7381 12.3775 14.8284 11.8354 15.0091L8.97709 15.9619C8.71035 16.0508 8.41626 15.9814 8.21744 15.7826C8.01862 15.5837 7.9492 15.2897 8.03811 15.0229L8.99089 12.1646C9.17157 11.6225 9.26191 11.3515 9.38344 11.0965C9.52679 10.7957 9.70249 10.5114 9.90743 10.2487C10.0812 10.0259 10.2832 9.82394 10.6872 9.41993L15.6033 4.50385C15.867 5.19804 16.3293 6.05663 17.1363 6.86366C17.9434 7.67069 18.802 8.13296 19.4962 8.39674L14.5801 13.3128Z"
|
||||
/>
|
||||
<path
|
||||
d="M20.5355 20.5355C22 19.0711 22 16.714 22 12C22 10.4517 22 9.15774 21.9481 8.0661L15.586 14.4283C15.2347 14.7797 14.9708 15.0437 14.6738 15.2753C14.3252 15.5473 13.948 15.7804 13.5488 15.9706C13.2088 16.1327 12.8546 16.2506 12.3833 16.4076L9.45143 17.3849C8.64568 17.6535 7.75734 17.4438 7.15678 16.8432C6.55621 16.2427 6.34651 15.3543 6.61509 14.5486L7.59235 11.6167C7.74936 11.1454 7.86732 10.7912 8.02935 10.4512C8.21958 10.052 8.45272 9.6748 8.72466 9.32615C8.9563 9.02918 9.22032 8.76528 9.57173 8.41404L15.9339 2.05188C14.8423 2 13.5483 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-title-button" class="hidden css-button"/>
|
||||
<div class="absolute z-30 top-7 right-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
value="{{ or .Data.Title "N/A" }}"
|
||||
class="p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Title "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div class="text-gray-500 inline-flex gap-2 relative">
|
||||
<p>Author</p>
|
||||
<label class="my-auto" for="edit-author-button">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21.1938 2.80624C22.2687 3.88124 22.2687 5.62415 21.1938 6.69914L20.6982 7.19469C20.5539 7.16345 20.3722 7.11589 20.1651 7.04404C19.6108 6.85172 18.8823 6.48827 18.197 5.803C17.5117 5.11774 17.1483 4.38923 16.956 3.8349C16.8841 3.62781 16.8366 3.44609 16.8053 3.30179L17.3009 2.80624C18.3759 1.73125 20.1188 1.73125 21.1938 2.80624Z"
|
||||
/>
|
||||
<path
|
||||
d="M14.5801 13.3128C14.1761 13.7168 13.9741 13.9188 13.7513 14.0926C13.4886 14.2975 13.2043 14.4732 12.9035 14.6166C12.6485 14.7381 12.3775 14.8284 11.8354 15.0091L8.97709 15.9619C8.71035 16.0508 8.41626 15.9814 8.21744 15.7826C8.01862 15.5837 7.9492 15.2897 8.03811 15.0229L8.99089 12.1646C9.17157 11.6225 9.26191 11.3515 9.38344 11.0965C9.52679 10.7957 9.70249 10.5114 9.90743 10.2487C10.0812 10.0259 10.2832 9.82394 10.6872 9.41993L15.6033 4.50385C15.867 5.19804 16.3293 6.05663 17.1363 6.86366C17.9434 7.67069 18.802 8.13296 19.4962 8.39674L14.5801 13.3128Z"
|
||||
/>
|
||||
<path
|
||||
d="M20.5355 20.5355C22 19.0711 22 16.714 22 12C22 10.4517 22 9.15774 21.9481 8.0661L15.586 14.4283C15.2347 14.7797 14.9708 15.0437 14.6738 15.2753C14.3252 15.5473 13.948 15.7804 13.5488 15.9706C13.2088 16.1327 12.8546 16.2506 12.3833 16.4076L9.45143 17.3849C8.64568 17.6535 7.75734 17.4438 7.15678 16.8432C6.55621 16.2427 6.34651 15.3543 6.61509 14.5486L7.59235 11.6167C7.74936 11.1454 7.86732 10.7912 8.02935 10.4512C8.21958 10.052 8.45272 9.6748 8.72466 9.32615C8.9563 9.02918 9.22032 8.76528 9.57173 8.41404L15.9339 2.05188C14.8423 2 13.5483 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-author-button" class="hidden css-button"/>
|
||||
|
||||
<div class="absolute z-30 top-7 right-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="author"
|
||||
name="author"
|
||||
value="{{ or .Data.Author "N/A" }}"
|
||||
class="p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Author "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-500">Time Read</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ .Data.TotalTimeMinutes }} Minutes
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-500">Progress</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ .Data.CurrentPage }} / {{ .Data.TotalPages }} ({{ .Data.Percentage }}%)
|
||||
</p>
|
||||
</div>
|
||||
<!--
|
||||
<div>
|
||||
<p class="text-gray-500">ISBN 10</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Isbn10 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-500">ISBN 13</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Isbn13 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<div class="text-gray-400 inline-flex gap-2 relative">
|
||||
<p>Title</p>
|
||||
<label class="my-auto" for="edit-title-button">
|
||||
<div class="text-gray-500 inline-flex gap-2 relative">
|
||||
<p>Description</p>
|
||||
<label class="my-auto" for="edit-description-button">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
@ -204,150 +346,139 @@
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-title-button" class="hidden css-button"/>
|
||||
<div class="absolute z-50 top-7 right-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
value="{{ or .Data.Title "N/A" }}"
|
||||
class="p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Title "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div class="text-gray-400 inline-flex gap-2 relative">
|
||||
<p>Author</p>
|
||||
<label class="my-auto" for="edit-author-button">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21.1938 2.80624C22.2687 3.88124 22.2687 5.62415 21.1938 6.69914L20.6982 7.19469C20.5539 7.16345 20.3722 7.11589 20.1651 7.04404C19.6108 6.85172 18.8823 6.48827 18.197 5.803C17.5117 5.11774 17.1483 4.38923 16.956 3.8349C16.8841 3.62781 16.8366 3.44609 16.8053 3.30179L17.3009 2.80624C18.3759 1.73125 20.1188 1.73125 21.1938 2.80624Z"
|
||||
/>
|
||||
<path
|
||||
d="M14.5801 13.3128C14.1761 13.7168 13.9741 13.9188 13.7513 14.0926C13.4886 14.2975 13.2043 14.4732 12.9035 14.6166C12.6485 14.7381 12.3775 14.8284 11.8354 15.0091L8.97709 15.9619C8.71035 16.0508 8.41626 15.9814 8.21744 15.7826C8.01862 15.5837 7.9492 15.2897 8.03811 15.0229L8.99089 12.1646C9.17157 11.6225 9.26191 11.3515 9.38344 11.0965C9.52679 10.7957 9.70249 10.5114 9.90743 10.2487C10.0812 10.0259 10.2832 9.82394 10.6872 9.41993L15.6033 4.50385C15.867 5.19804 16.3293 6.05663 17.1363 6.86366C17.9434 7.67069 18.802 8.13296 19.4962 8.39674L14.5801 13.3128Z"
|
||||
/>
|
||||
<path
|
||||
d="M20.5355 20.5355C22 19.0711 22 16.714 22 12C22 10.4517 22 9.15774 21.9481 8.0661L15.586 14.4283C15.2347 14.7797 14.9708 15.0437 14.6738 15.2753C14.3252 15.5473 13.948 15.7804 13.5488 15.9706C13.2088 16.1327 12.8546 16.2506 12.3833 16.4076L9.45143 17.3849C8.64568 17.6535 7.75734 17.4438 7.15678 16.8432C6.55621 16.2427 6.34651 15.3543 6.61509 14.5486L7.59235 11.6167C7.74936 11.1454 7.86732 10.7912 8.02935 10.4512C8.21958 10.052 8.45272 9.6748 8.72466 9.32615C8.9563 9.02918 9.22032 8.76528 9.57173 8.41404L15.9339 2.05188C14.8423 2 13.5483 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<input type="checkbox" id="edit-author-button" class="hidden css-button"/>
|
||||
|
||||
<div class="absolute z-50 top-7 right-0 p-3 transition-all duration-200 bg-gray-200 rounded shadow-lg shadow-gray-500 dark:shadow-gray-900 dark:bg-gray-600">
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 text-black dark:text-white text-sm"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="author"
|
||||
name="author"
|
||||
value="{{ or .Data.Author "N/A" }}"
|
||||
class="p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Author "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-400">Time Read</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ .Data.TotalTimeMinutes }} Minutes
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-400">Progress</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ .Data.CurrentPage }} / {{ .Data.TotalPages }} ({{ .Data.Percentage }}%)
|
||||
</p>
|
||||
</div>
|
||||
<!--
|
||||
<div>
|
||||
<p class="text-gray-400">ISBN 10</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Isbn10 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-gray-400">ISBN 13</p>
|
||||
<p class="font-medium text-lg">
|
||||
{{ or .Data.Isbn13 "N/A" }}
|
||||
</p>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<div class="text-gray-400 inline-flex gap-2 relative">
|
||||
<p>Description</p>
|
||||
<label class="my-auto" for="edit-description-button">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
class="cursor-pointer hover:text-gray-800 dark:hover:text-gray-100"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
<div class="relative font-medium text-justify hyphens-auto">
|
||||
<input type="checkbox" id="edit-description-button" class="hidden css-button"/>
|
||||
<div
|
||||
class="absolute h-full w-full min-h-[10em] z-30 top-1 right-0 gap-4 flex transition-all duration-200"
|
||||
>
|
||||
<path
|
||||
d="M21.1938 2.80624C22.2687 3.88124 22.2687 5.62415 21.1938 6.69914L20.6982 7.19469C20.5539 7.16345 20.3722 7.11589 20.1651 7.04404C19.6108 6.85172 18.8823 6.48827 18.197 5.803C17.5117 5.11774 17.1483 4.38923 16.956 3.8349C16.8841 3.62781 16.8366 3.44609 16.8053 3.30179L17.3009 2.80624C18.3759 1.73125 20.1188 1.73125 21.1938 2.80624Z"
|
||||
/>
|
||||
<path
|
||||
d="M14.5801 13.3128C14.1761 13.7168 13.9741 13.9188 13.7513 14.0926C13.4886 14.2975 13.2043 14.4732 12.9035 14.6166C12.6485 14.7381 12.3775 14.8284 11.8354 15.0091L8.97709 15.9619C8.71035 16.0508 8.41626 15.9814 8.21744 15.7826C8.01862 15.5837 7.9492 15.2897 8.03811 15.0229L8.99089 12.1646C9.17157 11.6225 9.26191 11.3515 9.38344 11.0965C9.52679 10.7957 9.70249 10.5114 9.90743 10.2487C10.0812 10.0259 10.2832 9.82394 10.6872 9.41993L15.6033 4.50385C15.867 5.19804 16.3293 6.05663 17.1363 6.86366C17.9434 7.67069 18.802 8.13296 19.4962 8.39674L14.5801 13.3128Z"
|
||||
/>
|
||||
<path
|
||||
d="M20.5355 20.5355C22 19.0711 22 16.714 22 12C22 10.4517 22 9.15774 21.9481 8.0661L15.586 14.4283C15.2347 14.7797 14.9708 15.0437 14.6738 15.2753C14.3252 15.5473 13.948 15.7804 13.5488 15.9706C13.2088 16.1327 12.8546 16.2506 12.3833 16.4076L9.45143 17.3849C8.64568 17.6535 7.75734 17.4438 7.15678 16.8432C6.55621 16.2427 6.34651 15.3543 6.61509 14.5486L7.59235 11.6167C7.74936 11.1454 7.86732 10.7912 8.02935 10.4512C8.21958 10.052 8.45272 9.6748 8.72466 9.32615C8.9563 9.02918 9.22032 8.76528 9.57173 8.41404L15.9339 2.05188C14.8423 2 13.5483 2 12 2C7.28595 2 4.92893 2 3.46447 3.46447C2 4.92893 2 7.28595 2 12C2 16.714 2 19.0711 3.46447 20.5355C4.92893 22 7.28595 22 12 22C16.714 22 19.0711 22 20.5355 20.5355Z"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
<img class="hidden md:block invisible rounded w-44 md:w-60 lg:w-80 object-fill" src="{{ .RelBase }}./documents/{{.Data.ID}}/cover"></img>
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-full text-black bg-gray-200 rounded shadow-lg shadow-gray-500 dark:text-white dark:shadow-gray-900 dark:bg-gray-600 text-sm p-3"
|
||||
>
|
||||
<textarea
|
||||
type="text"
|
||||
id="description"
|
||||
name="description"
|
||||
class="h-full w-full p-2 bg-gray-300 text-black dark:bg-gray-700 dark:text-white"
|
||||
>{{ or .Data.Description "N/A" }}</textarea>
|
||||
<button
|
||||
class="font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Save</button>
|
||||
</form>
|
||||
</div>
|
||||
<p>{{ or .Data.Description "N/A" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative font-medium text-justify hyphens-auto">
|
||||
<input type="checkbox" id="edit-description-button" class="hidden css-button"/>
|
||||
<div
|
||||
class="absolute h-full w-full min-h-[10em] z-50 top-1 right-0 gap-4 flex transition-all duration-200"
|
||||
|
||||
{{ if .MetadataError }}
|
||||
<div class="absolute top-0 left-0 w-full h-full z-50">
|
||||
<div class="fixed top-0 left-0 bg-black opacity-50 w-screen h-screen"></div>
|
||||
<div class="relative flex flex-col gap-4 p-4 max-h-[95%] bg-white dark:bg-gray-800 overflow-scroll -translate-x-2/4 -translate-y-2/4 top-1/2 left-1/2 w-5/6 overflow-hidden shadow rounded">
|
||||
<div class="text-center">
|
||||
<h3 class="text-lg font-bold leading-6 dark:text-gray-300">No Metadata Results Found</h3>
|
||||
</div>
|
||||
<a href="{{ .RelBase }}./documents/{{ .Data.ID }}"
|
||||
class="w-full text-center font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Back to Document</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<!-- Metadata Info -->
|
||||
{{ if .Metadata }}
|
||||
<div class="absolute top-0 left-0 w-full h-full z-50">
|
||||
<div class="fixed top-0 left-0 bg-black opacity-50 w-screen h-screen"></div>
|
||||
<div class="relative max-h-[95%] bg-white dark:bg-gray-800 overflow-scroll -translate-x-2/4 -translate-y-2/4 top-1/2 left-1/2 w-5/6 overflow-hidden shadow rounded">
|
||||
<div class="py-5 text-center">
|
||||
<h3 class="text-lg font-bold leading-6 dark:text-gray-300">Metadata Results</h3>
|
||||
</div>
|
||||
<form
|
||||
id="metadata-save"
|
||||
method="POST"
|
||||
action="{{ .RelBase }}./documents/{{ .Data.ID }}/edit"
|
||||
class="text-black dark:text-white border-b dark:border-black"
|
||||
>
|
||||
<img class="hidden md:block invisible rounded w-40 md:w-60 lg:w-80 object-fill" src="../documents/{{.Data.ID}}/cover"></img>
|
||||
<form
|
||||
method="POST"
|
||||
action="./{{ .Data.ID }}/edit"
|
||||
class="flex flex-col gap-2 w-full text-black bg-gray-200 rounded shadow-lg shadow-gray-500 dark:text-white dark:shadow-gray-900 dark:bg-gray-600 text-sm p-3"
|
||||
>
|
||||
<textarea
|
||||
type="text"
|
||||
id="description"
|
||||
name="description"
|
||||
class="h-full w-full p-2 bg-gray-400 text-black dark:bg-gray-700 dark:text-white"
|
||||
>{{ or .Data.Description "N/A" }}</textarea>
|
||||
<button class="font-medium px-2 py-1 text-white bg-gray-500 dark:text-gray-800 dark:bg-gray-400 hover:bg-gray-800 dark:hover:bg-gray-100" type="submit">Save</button>
|
||||
</form>
|
||||
<dl>
|
||||
<div class="p-3 bg-gray-100 dark:bg-gray-900 grid grid-cols-3 gap-4 sm:px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
Cover
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
|
||||
<img class="rounded object-fill h-32" src="https://books.google.com/books/content/images/frontcover/{{ .Metadata.GBID }}?fife=w480-h690"></img>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="p-3 bg-white dark:bg-gray-800 grid grid-cols-3 gap-4 sm:px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
Title
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
|
||||
{{ or .Metadata.Title "N/A" }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-100 dark:bg-gray-900 grid grid-cols-3 gap-4 sm:px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
Author
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
|
||||
{{ or .Metadata.Author "N/A" }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="p-3 bg-white dark:bg-gray-800 grid grid-cols-3 gap-4 sm:px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
ISBN 10
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
|
||||
{{ or .Metadata.ISBN10 "N/A" }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-100 dark:bg-gray-900 grid grid-cols-3 gap-4 sm:px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
ISBN 13
|
||||
</dt>
|
||||
<dd class="mt-1 text-sm sm:mt-0 sm:col-span-2">
|
||||
{{ or .Metadata.ISBN13 "N/A" }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="p-3 bg-white dark:bg-gray-800 sm:grid sm:grid-cols-3 sm:gap-4 px-6">
|
||||
<dt class="my-auto font-medium text-gray-500">
|
||||
Description
|
||||
</dt>
|
||||
<dd class="max-h-[10em] overflow-scroll mt-1 sm:mt-0 sm:col-span-2">
|
||||
{{ or .Metadata.Description "N/A" }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div class="hidden">
|
||||
<input type="text" id="title" name="title" value="{{ .Metadata.Title }}">
|
||||
<input type="text" id="author" name="author" value="{{ .Metadata.Author }}">
|
||||
<input type="text" id="description" name="description" value="{{ .Metadata.Description }}">
|
||||
<input type="text" id="isbn_10" name="isbn_10" value="{{ .Metadata.ISBN10 }}">
|
||||
<input type="text" id="isbn_13" name="isbn_13" value="{{ .Metadata.ISBN13 }}">
|
||||
<input type="text" id="cover_gbid" name="cover_gbid" value="{{ .Metadata.GBID }}">
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex justify-end gap-4 m-4">
|
||||
<a href="{{ .RelBase }}./documents/{{ .Data.ID }}"
|
||||
class="w-24 text-center font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Cancel</a>
|
||||
<button
|
||||
form="metadata-save"
|
||||
class="w-24 font-medium px-2 py-1 text-white bg-gray-500 dark:bg-gray-500 dark:text-gray-800 hover:bg-gray-800 dark:hover:bg-gray-100"
|
||||
type="submit"
|
||||
>Save</button>
|
||||
</div>
|
||||
<p>{{ or .Data.Description "N/A" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.css-button:checked + div {
|
||||
visibility: visible;
|
||||
|