mirror of
https://github.com/Radiquum/photos.git
synced 2025-04-05 15:54:31 +00:00
feat/admin: finished home page ui
This commit is contained in:
parent
a80947d892
commit
5e3116d46f
4 changed files with 406 additions and 14 deletions
|
@ -13,6 +13,7 @@ import firebase_admin
|
||||||
from firebase_admin import firestore, credentials
|
from firebase_admin import firestore, credentials
|
||||||
from firebase_admin import exceptions as FB_EXCEPTION
|
from firebase_admin import exceptions as FB_EXCEPTION
|
||||||
from google.api_core import exceptions as GOOGLE_EXCEPTION
|
from google.api_core import exceptions as GOOGLE_EXCEPTION
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
UPLOAD_FOLDER = "./temp"
|
UPLOAD_FOLDER = "./temp"
|
||||||
|
@ -36,12 +37,33 @@ db = firestore.client()
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def Home():
|
def Home():
|
||||||
from urllib.request import urlopen
|
objects = []
|
||||||
|
|
||||||
print(urlopen("https://www.howsmyssl.com/a/check").read())
|
tag = request.args.get('tag')
|
||||||
# objects = s3.list_objects(Bucket=os.getenv("AWS_BUCKET"))['Contents']
|
if tag:
|
||||||
# return render_template("Index.html", objects=objects)
|
db_objects = (
|
||||||
return render_template("Index.html", page_title="Home")
|
db.collection(os.getenv("PREFIX"))
|
||||||
|
.where("tags", "array_contains", tag)
|
||||||
|
.order_by("date", direction=firestore.Query.DESCENDING)
|
||||||
|
.stream()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
db_objects = (
|
||||||
|
db.collection(os.getenv("PREFIX"))
|
||||||
|
.order_by("date", direction=firestore.Query.DESCENDING)
|
||||||
|
.stream()
|
||||||
|
)
|
||||||
|
|
||||||
|
for object in db_objects:
|
||||||
|
name = object.id
|
||||||
|
img = f"{object.id.split(".")[0]}/{object.id}"
|
||||||
|
|
||||||
|
obj = object.to_dict()
|
||||||
|
date = datetime.fromtimestamp(float(float(str(obj['date'])[:10]))).strftime("%d/%m/%Y")
|
||||||
|
|
||||||
|
objects.append({"name": name, "img": img, **obj, "date": date})
|
||||||
|
|
||||||
|
return render_template("Index.html", objects=objects, page_title="Home")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/upload/")
|
@app.route("/upload/")
|
||||||
|
@ -138,7 +160,11 @@ def ApiUpload():
|
||||||
},
|
},
|
||||||
request.files["file"].filename,
|
request.files["file"].filename,
|
||||||
)
|
)
|
||||||
except (FB_EXCEPTION.ConflictError, FB_EXCEPTION.AlreadyExistsError, GOOGLE_EXCEPTION.AlreadyExists) as e:
|
except (
|
||||||
|
FB_EXCEPTION.ConflictError,
|
||||||
|
FB_EXCEPTION.AlreadyExistsError,
|
||||||
|
GOOGLE_EXCEPTION.AlreadyExists,
|
||||||
|
) as e:
|
||||||
Image.close()
|
Image.close()
|
||||||
os.remove(os.path.join(app.config["UPLOAD_FOLDER"], filename))
|
os.remove(os.path.join(app.config["UPLOAD_FOLDER"], filename))
|
||||||
return Response(
|
return Response(
|
||||||
|
|
|
@ -1197,6 +1197,12 @@
|
||||||
.me-2 {
|
.me-2 {
|
||||||
margin-inline-end: calc(var(--spacing) * 2);
|
margin-inline-end: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
.-mt-1 {
|
||||||
|
margin-top: calc(var(--spacing) * -1);
|
||||||
|
}
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.mt-2 {
|
.mt-2 {
|
||||||
margin-top: calc(var(--spacing) * 2);
|
margin-top: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
@ -1586,6 +1592,9 @@
|
||||||
.inline-flex {
|
.inline-flex {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
.list-item {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
.table {
|
.table {
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
@ -1601,9 +1610,15 @@
|
||||||
.h-8 {
|
.h-8 {
|
||||||
height: calc(var(--spacing) * 8);
|
height: calc(var(--spacing) * 8);
|
||||||
}
|
}
|
||||||
|
.h-32 {
|
||||||
|
height: calc(var(--spacing) * 32);
|
||||||
|
}
|
||||||
.h-64 {
|
.h-64 {
|
||||||
height: calc(var(--spacing) * 64);
|
height: calc(var(--spacing) * 64);
|
||||||
}
|
}
|
||||||
|
.h-128 {
|
||||||
|
height: calc(var(--spacing) * 128);
|
||||||
|
}
|
||||||
.h-\[calc\(100\%-1rem\)\] {
|
.h-\[calc\(100\%-1rem\)\] {
|
||||||
height: calc(100% - 1rem);
|
height: calc(100% - 1rem);
|
||||||
}
|
}
|
||||||
|
@ -1613,6 +1628,9 @@
|
||||||
.max-h-full {
|
.max-h-full {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
.min-h-32 {
|
||||||
|
min-height: calc(var(--spacing) * 32);
|
||||||
|
}
|
||||||
.datatable-table {
|
.datatable-table {
|
||||||
.datatable-wrapper & {
|
.datatable-wrapper & {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1696,6 +1714,9 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.w-1 {
|
||||||
|
width: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.w-1\/2 {
|
.w-1\/2 {
|
||||||
width: calc(1/2 * 100%);
|
width: calc(1/2 * 100%);
|
||||||
}
|
}
|
||||||
|
@ -1711,6 +1732,9 @@
|
||||||
.w-8 {
|
.w-8 {
|
||||||
width: calc(var(--spacing) * 8);
|
width: calc(var(--spacing) * 8);
|
||||||
}
|
}
|
||||||
|
.w-32 {
|
||||||
|
width: calc(var(--spacing) * 32);
|
||||||
|
}
|
||||||
.w-64 {
|
.w-64 {
|
||||||
width: calc(var(--spacing) * 64);
|
width: calc(var(--spacing) * 64);
|
||||||
}
|
}
|
||||||
|
@ -1723,6 +1747,9 @@
|
||||||
.max-w-2xl {
|
.max-w-2xl {
|
||||||
max-width: var(--container-2xl);
|
max-width: var(--container-2xl);
|
||||||
}
|
}
|
||||||
|
.max-w-32 {
|
||||||
|
max-width: calc(var(--spacing) * 32);
|
||||||
|
}
|
||||||
.datatable-input {
|
.datatable-input {
|
||||||
.datatable-wrapper .datatable-search & {
|
.datatable-wrapper .datatable-search & {
|
||||||
color: var(--color-gray-900);
|
color: var(--color-gray-900);
|
||||||
|
@ -1791,6 +1818,9 @@
|
||||||
.flex-shrink {
|
.flex-shrink {
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
|
.border-collapse {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
.-translate-x-full {
|
.-translate-x-full {
|
||||||
--tw-translate-x: -100%;
|
--tw-translate-x: -100%;
|
||||||
translate: var(--tw-translate-x) var(--tw-translate-y);
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
||||||
|
@ -1835,9 +1865,18 @@
|
||||||
.resize-none {
|
.resize-none {
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
.grid-cols-2 {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
.grid-cols-3 {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
.grid-cols-4 {
|
.grid-cols-4 {
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
.grid-cols-6 {
|
||||||
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||||
|
}
|
||||||
.grid-cols-7 {
|
.grid-cols-7 {
|
||||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
@ -1868,15 +1907,18 @@
|
||||||
.justify-start {
|
.justify-start {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
.gap-1 {
|
||||||
|
gap: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.gap-2 {
|
.gap-2 {
|
||||||
gap: calc(var(--spacing) * 2);
|
gap: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
.gap-3 {
|
||||||
|
gap: calc(var(--spacing) * 3);
|
||||||
|
}
|
||||||
.gap-4 {
|
.gap-4 {
|
||||||
gap: calc(var(--spacing) * 4);
|
gap: calc(var(--spacing) * 4);
|
||||||
}
|
}
|
||||||
.gap-8 {
|
|
||||||
gap: calc(var(--spacing) * 8);
|
|
||||||
}
|
|
||||||
.space-y-6 {
|
.space-y-6 {
|
||||||
:where(& > :not(:last-child)) {
|
:where(& > :not(:last-child)) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
|
@ -1950,6 +1992,14 @@
|
||||||
border-bottom-style: var(--tw-border-style);
|
border-bottom-style: var(--tw-border-style);
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
}
|
}
|
||||||
|
.border-l {
|
||||||
|
border-left-style: var(--tw-border-style);
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
.border-l-2 {
|
||||||
|
border-left-style: var(--tw-border-style);
|
||||||
|
border-left-width: 2px;
|
||||||
|
}
|
||||||
.border-dashed {
|
.border-dashed {
|
||||||
--tw-border-style: dashed;
|
--tw-border-style: dashed;
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
|
@ -2102,12 +2152,18 @@
|
||||||
.border-gray-300 {
|
.border-gray-300 {
|
||||||
border-color: var(--color-gray-300);
|
border-color: var(--color-gray-300);
|
||||||
}
|
}
|
||||||
|
.border-gray-500 {
|
||||||
|
border-color: var(--color-gray-500);
|
||||||
|
}
|
||||||
.border-gray-600 {
|
.border-gray-600 {
|
||||||
border-color: var(--color-gray-600);
|
border-color: var(--color-gray-600);
|
||||||
}
|
}
|
||||||
.border-gray-700 {
|
.border-gray-700 {
|
||||||
border-color: var(--color-gray-700);
|
border-color: var(--color-gray-700);
|
||||||
}
|
}
|
||||||
|
.border-gray-800 {
|
||||||
|
border-color: var(--color-gray-800);
|
||||||
|
}
|
||||||
.apexcharts-active {
|
.apexcharts-active {
|
||||||
.apexcharts-canvas .apexcharts-tooltip-series-group& .apexcharts-tooltip-y-group {
|
.apexcharts-canvas .apexcharts-tooltip-series-group& .apexcharts-tooltip-y-group {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
@ -2146,6 +2202,18 @@
|
||||||
padding-top: 0.75rem !important;
|
padding-top: 0.75rem !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.bg-black {
|
||||||
|
background-color: var(--color-black);
|
||||||
|
}
|
||||||
|
.bg-black\/25 {
|
||||||
|
background-color: color-mix(in oklab, var(--color-black) 25%, transparent);
|
||||||
|
}
|
||||||
|
.bg-black\/50 {
|
||||||
|
background-color: color-mix(in oklab, var(--color-black) 50%, transparent);
|
||||||
|
}
|
||||||
|
.bg-black\/75 {
|
||||||
|
background-color: color-mix(in oklab, var(--color-black) 75%, transparent);
|
||||||
|
}
|
||||||
.bg-blue-700 {
|
.bg-blue-700 {
|
||||||
background-color: var(--color-blue-700);
|
background-color: var(--color-blue-700);
|
||||||
}
|
}
|
||||||
|
@ -2167,12 +2235,24 @@
|
||||||
.bg-gray-800 {
|
.bg-gray-800 {
|
||||||
background-color: var(--color-gray-800);
|
background-color: var(--color-gray-800);
|
||||||
}
|
}
|
||||||
|
.bg-gray-900 {
|
||||||
|
background-color: var(--color-gray-900);
|
||||||
|
}
|
||||||
.bg-gray-900\/50 {
|
.bg-gray-900\/50 {
|
||||||
background-color: color-mix(in oklab, var(--color-gray-900) 50%, transparent);
|
background-color: color-mix(in oklab, var(--color-gray-900) 50%, transparent);
|
||||||
}
|
}
|
||||||
.bg-red-700 {
|
.bg-red-700 {
|
||||||
background-color: var(--color-red-700);
|
background-color: var(--color-red-700);
|
||||||
}
|
}
|
||||||
|
.bg-slate-500 {
|
||||||
|
background-color: var(--color-slate-500);
|
||||||
|
}
|
||||||
|
.bg-slate-700 {
|
||||||
|
background-color: var(--color-slate-700);
|
||||||
|
}
|
||||||
|
.bg-slate-800 {
|
||||||
|
background-color: var(--color-slate-800);
|
||||||
|
}
|
||||||
.bg-slate-900 {
|
.bg-slate-900 {
|
||||||
background-color: var(--color-slate-900);
|
background-color: var(--color-slate-900);
|
||||||
}
|
}
|
||||||
|
@ -2198,6 +2278,45 @@
|
||||||
background-color: var(--color-gray-700);
|
background-color: var(--color-gray-700);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.bg-gradient-to-t {
|
||||||
|
--tw-gradient-position: to top in oklab;
|
||||||
|
background-image: linear-gradient(var(--tw-gradient-stops));
|
||||||
|
}
|
||||||
|
.from-black {
|
||||||
|
--tw-gradient-from: var(--color-black);
|
||||||
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||||
|
}
|
||||||
|
.from-black\/75 {
|
||||||
|
--tw-gradient-from: color-mix(in oklab, var(--color-black) 75%, transparent);
|
||||||
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||||
|
}
|
||||||
|
.from-black\/80 {
|
||||||
|
--tw-gradient-from: color-mix(in oklab, var(--color-black) 80%, transparent);
|
||||||
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||||
|
}
|
||||||
|
.from-black\/90 {
|
||||||
|
--tw-gradient-from: color-mix(in oklab, var(--color-black) 90%, transparent);
|
||||||
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||||
|
}
|
||||||
|
.to-transparent {
|
||||||
|
--tw-gradient-to: transparent;
|
||||||
|
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
|
||||||
|
}
|
||||||
|
.to-25\% {
|
||||||
|
--tw-gradient-to-position: 25%;
|
||||||
|
}
|
||||||
|
.to-80\% {
|
||||||
|
--tw-gradient-to-position: 80%;
|
||||||
|
}
|
||||||
|
.to-90\% {
|
||||||
|
--tw-gradient-to-position: 90%;
|
||||||
|
}
|
||||||
|
.to-95\% {
|
||||||
|
--tw-gradient-to-position: 95%;
|
||||||
|
}
|
||||||
|
.to-100\% {
|
||||||
|
--tw-gradient-to-position: 100%;
|
||||||
|
}
|
||||||
.apexcharts-text {
|
.apexcharts-text {
|
||||||
.apexcharts-datalabels-group &.apexcharts-datalabel-value {
|
.apexcharts-datalabels-group &.apexcharts-datalabel-value {
|
||||||
fill: var(--color-gray-900) !important;
|
fill: var(--color-gray-900) !important;
|
||||||
|
@ -2281,6 +2400,12 @@
|
||||||
.object-contain {
|
.object-contain {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
.object-cover {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.object-scale-down {
|
||||||
|
object-fit: scale-down;
|
||||||
|
}
|
||||||
.apexcharts-legend {
|
.apexcharts-legend {
|
||||||
.apexcharts-canvas & {
|
.apexcharts-canvas & {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
@ -2312,12 +2437,18 @@
|
||||||
.p-8 {
|
.p-8 {
|
||||||
padding: calc(var(--spacing) * 8);
|
padding: calc(var(--spacing) * 8);
|
||||||
}
|
}
|
||||||
|
.p-\[\;r<EFBFBD>\] {
|
||||||
|
padding: ;r<EFBFBD>;
|
||||||
|
}
|
||||||
.px-2 {
|
.px-2 {
|
||||||
padding-inline: calc(var(--spacing) * 2);
|
padding-inline: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
.px-5 {
|
.px-5 {
|
||||||
padding-inline: calc(var(--spacing) * 5);
|
padding-inline: calc(var(--spacing) * 5);
|
||||||
}
|
}
|
||||||
|
.py-1 {
|
||||||
|
padding-block: calc(var(--spacing) * 1);
|
||||||
|
}
|
||||||
.py-2 {
|
.py-2 {
|
||||||
padding-block: calc(var(--spacing) * 2);
|
padding-block: calc(var(--spacing) * 2);
|
||||||
}
|
}
|
||||||
|
@ -2336,6 +2467,18 @@
|
||||||
.pt-5 {
|
.pt-5 {
|
||||||
padding-top: calc(var(--spacing) * 5);
|
padding-top: calc(var(--spacing) * 5);
|
||||||
}
|
}
|
||||||
|
.pt-8 {
|
||||||
|
padding-top: calc(var(--spacing) * 8);
|
||||||
|
}
|
||||||
|
.pt-12 {
|
||||||
|
padding-top: calc(var(--spacing) * 12);
|
||||||
|
}
|
||||||
|
.pt-16 {
|
||||||
|
padding-top: calc(var(--spacing) * 16);
|
||||||
|
}
|
||||||
|
.pt-24 {
|
||||||
|
padding-top: calc(var(--spacing) * 24);
|
||||||
|
}
|
||||||
.search-filtering-row {
|
.search-filtering-row {
|
||||||
.datatable-wrapper .datatable-container thead tr& th {
|
.datatable-wrapper .datatable-container thead tr& th {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
@ -2507,9 +2650,24 @@
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.text-blue-200 {
|
||||||
|
color: var(--color-blue-200);
|
||||||
|
}
|
||||||
|
.text-blue-300 {
|
||||||
|
color: var(--color-blue-300);
|
||||||
|
}
|
||||||
|
.text-blue-400 {
|
||||||
|
color: var(--color-blue-400);
|
||||||
|
}
|
||||||
|
.text-blue-500 {
|
||||||
|
color: var(--color-blue-500);
|
||||||
|
}
|
||||||
.text-blue-600 {
|
.text-blue-600 {
|
||||||
color: var(--color-blue-600);
|
color: var(--color-blue-600);
|
||||||
}
|
}
|
||||||
|
.text-gray-200 {
|
||||||
|
color: var(--color-gray-200);
|
||||||
|
}
|
||||||
.text-gray-300 {
|
.text-gray-300 {
|
||||||
color: var(--color-gray-300);
|
color: var(--color-gray-300);
|
||||||
}
|
}
|
||||||
|
@ -2534,6 +2692,9 @@
|
||||||
.uppercase {
|
.uppercase {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
.underline {
|
||||||
|
text-decoration-line: underline;
|
||||||
|
}
|
||||||
.opacity-0 {
|
.opacity-0 {
|
||||||
opacity: 0%;
|
opacity: 0%;
|
||||||
}
|
}
|
||||||
|
@ -2621,6 +2782,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.hover\:bg-gray-500 {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
background-color: var(--color-gray-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.hover\:bg-gray-600 {
|
.hover\:bg-gray-600 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
|
@ -2642,6 +2810,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.hover\:text-blue-400 {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
color: var(--color-blue-400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.hover\:text-blue-500 {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
color: var(--color-blue-500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.hover\:text-blue-600 {
|
.hover\:text-blue-600 {
|
||||||
&:hover {
|
&:hover {
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
|
@ -2670,6 +2852,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.hover\:text-white {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
color: var(--color-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.hover\:underline {
|
||||||
|
&:hover {
|
||||||
|
@media (hover: hover) {
|
||||||
|
text-decoration-line: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus\:z-10 {
|
.focus\:z-10 {
|
||||||
&:focus {
|
&:focus {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
@ -2707,6 +2903,11 @@
|
||||||
--tw-ring-color: var(--color-gray-200);
|
--tw-ring-color: var(--color-gray-200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.focus\:ring-gray-800 {
|
||||||
|
&:focus {
|
||||||
|
--tw-ring-color: var(--color-gray-800);
|
||||||
|
}
|
||||||
|
}
|
||||||
.focus\:ring-red-300 {
|
.focus\:ring-red-300 {
|
||||||
&:focus {
|
&:focus {
|
||||||
--tw-ring-color: var(--color-red-300);
|
--tw-ring-color: var(--color-red-300);
|
||||||
|
@ -3407,6 +3608,48 @@
|
||||||
inherits: false;
|
inherits: false;
|
||||||
initial-value: solid;
|
initial-value: solid;
|
||||||
}
|
}
|
||||||
|
@property --tw-gradient-position {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-from {
|
||||||
|
syntax: "<color>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: #0000;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-via {
|
||||||
|
syntax: "<color>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: #0000;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-to {
|
||||||
|
syntax: "<color>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: #0000;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-stops {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-via-stops {
|
||||||
|
syntax: "*";
|
||||||
|
inherits: false;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-from-position {
|
||||||
|
syntax: "<length-percentage>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: 0%;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-via-position {
|
||||||
|
syntax: "<length-percentage>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: 50%;
|
||||||
|
}
|
||||||
|
@property --tw-gradient-to-position {
|
||||||
|
syntax: "<length-percentage>";
|
||||||
|
inherits: false;
|
||||||
|
initial-value: 100%;
|
||||||
|
}
|
||||||
@property --tw-leading {
|
@property --tw-leading {
|
||||||
syntax: "*";
|
syntax: "*";
|
||||||
inherits: false;
|
inherits: false;
|
||||||
|
|
|
@ -1,12 +1,135 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="flex gap-1 mb-4">
|
||||||
|
<button type="button" id="list-view-btn"
|
||||||
|
class="border focus:ring-4 focus:outline-none font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center me-2 border-gray-500 text-gray-500 hover:text-white focus:ring-gray-800 hover:bg-gray-500">
|
||||||
|
<svg class="w-6 h-6 text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||||
|
fill="none" viewBox="0 0 24 24">
|
||||||
|
<path stroke="currentColor" stroke-linecap="round" stroke-width="2"
|
||||||
|
d="M9 8h10M9 12h10M9 16h10M4.99 8H5m-.02 4h.01m0 4H5" />
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">List View</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" id="grid-view-btn"
|
||||||
|
class="border focus:ring-4 focus:outline-none font-medium rounded-lg text-sm p-2.5 text-center inline-flex items-center me-2 border-gray-500 text-gray-500 hover:text-white focus:ring-gray-800 hover:bg-gray-500">
|
||||||
|
<svg class="w-6 h-6 text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
||||||
|
fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path fill-rule="evenodd"
|
||||||
|
d="M4.857 3A1.857 1.857 0 0 0 3 4.857v4.286C3 10.169 3.831 11 4.857 11h4.286A1.857 1.857 0 0 0 11 9.143V4.857A1.857 1.857 0 0 0 9.143 3H4.857Zm10 0A1.857 1.857 0 0 0 13 4.857v4.286c0 1.026.831 1.857 1.857 1.857h4.286A1.857 1.857 0 0 0 21 9.143V4.857A1.857 1.857 0 0 0 19.143 3h-4.286Zm-10 10A1.857 1.857 0 0 0 3 14.857v4.286C3 20.169 3.831 21 4.857 21h4.286A1.857 1.857 0 0 0 11 19.143v-4.286A1.857 1.857 0 0 0 9.143 13H4.857Zm10 0A1.857 1.857 0 0 0 13 14.857v4.286c0 1.026.831 1.857 1.857 1.857h4.286A1.857 1.857 0 0 0 21 19.143v-4.286A1.857 1.857 0 0 0 19.143 13h-4.286Z"
|
||||||
|
clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Grid View</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-col gap-4 hidden" id="list-view">
|
||||||
|
{% for object in objects %}
|
||||||
|
<div class="flex gap-4 rounded-lg bg-slate-800 p-2 w-full min-h-32 items-start">
|
||||||
|
<a href="/edit/{{ object.name }}" class="hover:underline">
|
||||||
|
<img src="https://s3.tebi.io/radiquum-photos/{{ object.img }}" alt=""
|
||||||
|
class="max-w-32 rounded-lg object-scale-down" />
|
||||||
|
</a>
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<a href="/edit/{{ object.name }}" class="hover:underline">
|
||||||
|
<div>
|
||||||
|
<p class="text-sm text-gray-400">{{ object.date }}</p>
|
||||||
|
<p class="text-xl -mt-1">{{ object.name }}</p>
|
||||||
|
<p class="text-sm text-gray-400">{{ object.width }} x {{ object.height }}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<p>{{ object.alt or "WARNING: NO ALT!" }}</p>
|
||||||
|
{% if object.urls %}
|
||||||
|
<div class="flex gap-3 flex-wrap">
|
||||||
|
<p>urls:</p>
|
||||||
|
{% for url in object.urls %}
|
||||||
|
<a href="{{ url.value }}" class="text-blue-300 hover:text-blue-500 hover:underline">{{ url.name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if object.tags %}
|
||||||
|
<div class="flex gap-1 flex-wrap">
|
||||||
|
{% for tag in object.tags %}
|
||||||
|
<a href="{{ url_for('Home') }}?tag={{ tag }}" class="hover:underline">
|
||||||
|
<div class="bg-slate-900 rounded-lg px-2 py-1">
|
||||||
|
#{{ tag }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gap-4 hidden grid-cols-3" id="grid-view">
|
||||||
|
{% for object in objects %}
|
||||||
|
<div class="w-full h-128 bg-slate-800 p-2 relative">
|
||||||
|
<a href="/edit/{{ object.name }}">
|
||||||
|
<img class="absolute w-full h-full inset-0 object-cover"
|
||||||
|
src="https://s3.tebi.io/radiquum-photos/{{ object.img }}" alt="" />
|
||||||
|
</a>
|
||||||
|
<div
|
||||||
|
class="absolute bottom-0 left-0 w-full px-2 pb-2 pt-16 bg-gradient-to-t from-black/90 to-transparent to-95%">
|
||||||
|
<div>
|
||||||
|
<p class="text-xl -mt-1">{{ object.name }}</p>
|
||||||
|
<div class="flex gap-2 text-gray-300 text-sm">
|
||||||
|
<p>{{ object.date }}</p>
|
||||||
|
<p>{{ object.width }} x {{ object.height }}</p>
|
||||||
|
</div>
|
||||||
|
{% if object.urls %}
|
||||||
|
<div class="flex gap-2 flex-wrap">
|
||||||
|
<p>urls:</p>
|
||||||
|
{% for url in object.urls %}
|
||||||
|
<a href="{{ url.value }}" class="text-blue-300 hover:text-blue-500 hover:underline">{{ url.name
|
||||||
|
}}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if object.tags %}
|
||||||
|
<div class="flex gap-2 flex-wrap">
|
||||||
|
{% for tag in object.tags %}
|
||||||
|
<a href="{{ url_for('Home') }}?tag={{ tag }}" class="hover:underline">#{{ tag }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- {% for object in objects %}
|
<script>
|
||||||
<img src="https://s3.tebi.io/radiquum-photos/{{ object['Key'] }}" />
|
|
||||||
<p>{{ object['Key'] }}</p>
|
const listView = document.getElementById('list-view')
|
||||||
{% endfor %} -->
|
const gridView = document.getElementById('grid-view')
|
||||||
|
|
||||||
|
const listViewBtn = document.getElementById('list-view-btn')
|
||||||
|
const gridViewBtn = document.getElementById('grid-view-btn')
|
||||||
|
|
||||||
|
let view = localStorage.getItem('view') || 'list'
|
||||||
|
if (view === 'list') {
|
||||||
|
listView.classList.remove('hidden')
|
||||||
|
listView.classList.add('flex')
|
||||||
|
} else if (view === 'grid') {
|
||||||
|
gridView.classList.remove('hidden')
|
||||||
|
gridView.classList.add('grid')
|
||||||
|
}
|
||||||
|
|
||||||
|
listViewBtn.addEventListener('click', () => {
|
||||||
|
listView.classList.remove('hidden')
|
||||||
|
listView.classList.add('flex')
|
||||||
|
gridView.classList.add('hidden')
|
||||||
|
localStorage.setItem('view', 'list')
|
||||||
|
})
|
||||||
|
gridViewBtn.addEventListener('click', () => {
|
||||||
|
gridView.classList.remove('hidden')
|
||||||
|
gridView.classList.add('grid')
|
||||||
|
listView.classList.add('hidden')
|
||||||
|
localStorage.setItem('view', 'grid')
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -94,7 +94,7 @@
|
||||||
tagInp.addEventListener('input', (e) => {
|
tagInp.addEventListener('input', (e) => {
|
||||||
if (e.target.value.includes(',')) {
|
if (e.target.value.includes(',')) {
|
||||||
const tag = e.target.value.split(',')[0].trim().replaceAll(" ", "_").toLowerCase();
|
const tag = e.target.value.split(',')[0].trim().replaceAll(" ", "_").toLowerCase();
|
||||||
if (tags.includes(tag)) {
|
if (tags.includes(tag) || !tag) {
|
||||||
tagInp.value = '';
|
tagInp.value = '';
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue