diff --git a/admin/main.py b/admin/main.py index eb0be5d..c1e339b 100644 --- a/admin/main.py +++ b/admin/main.py @@ -13,6 +13,7 @@ import firebase_admin from firebase_admin import firestore, credentials from firebase_admin import exceptions as FB_EXCEPTION from google.api_core import exceptions as GOOGLE_EXCEPTION +from datetime import datetime load_dotenv() UPLOAD_FOLDER = "./temp" @@ -36,12 +37,33 @@ db = firestore.client() @app.route("/") def Home(): - from urllib.request import urlopen + objects = [] - print(urlopen("https://www.howsmyssl.com/a/check").read()) - # objects = s3.list_objects(Bucket=os.getenv("AWS_BUCKET"))['Contents'] - # return render_template("Index.html", objects=objects) - return render_template("Index.html", page_title="Home") + tag = request.args.get('tag') + if tag: + db_objects = ( + 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/") @@ -138,7 +160,11 @@ def ApiUpload(): }, 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() os.remove(os.path.join(app.config["UPLOAD_FOLDER"], filename)) return Response( diff --git a/admin/static/tailwind.css b/admin/static/tailwind.css index 91f0315..23daf4d 100644 --- a/admin/static/tailwind.css +++ b/admin/static/tailwind.css @@ -1197,6 +1197,12 @@ .me-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 { margin-top: calc(var(--spacing) * 2); } @@ -1586,6 +1592,9 @@ .inline-flex { display: inline-flex; } + .list-item { + display: list-item; + } .table { display: table; } @@ -1601,9 +1610,15 @@ .h-8 { height: calc(var(--spacing) * 8); } + .h-32 { + height: calc(var(--spacing) * 32); + } .h-64 { height: calc(var(--spacing) * 64); } + .h-128 { + height: calc(var(--spacing) * 128); + } .h-\[calc\(100\%-1rem\)\] { height: calc(100% - 1rem); } @@ -1613,6 +1628,9 @@ .max-h-full { max-height: 100%; } + .min-h-32 { + min-height: calc(var(--spacing) * 32); + } .datatable-table { .datatable-wrapper & { width: 100%; @@ -1696,6 +1714,9 @@ text-align: center; } } + .w-1 { + width: calc(var(--spacing) * 1); + } .w-1\/2 { width: calc(1/2 * 100%); } @@ -1711,6 +1732,9 @@ .w-8 { width: calc(var(--spacing) * 8); } + .w-32 { + width: calc(var(--spacing) * 32); + } .w-64 { width: calc(var(--spacing) * 64); } @@ -1723,6 +1747,9 @@ .max-w-2xl { max-width: var(--container-2xl); } + .max-w-32 { + max-width: calc(var(--spacing) * 32); + } .datatable-input { .datatable-wrapper .datatable-search & { color: var(--color-gray-900); @@ -1791,6 +1818,9 @@ .flex-shrink { flex-shrink: 1; } + .border-collapse { + border-collapse: collapse; + } .-translate-x-full { --tw-translate-x: -100%; translate: var(--tw-translate-x) var(--tw-translate-y); @@ -1835,9 +1865,18 @@ .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-template-columns: repeat(4, minmax(0, 1fr)); } + .grid-cols-6 { + grid-template-columns: repeat(6, minmax(0, 1fr)); + } .grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); } @@ -1868,15 +1907,18 @@ .justify-start { justify-content: flex-start; } + .gap-1 { + gap: calc(var(--spacing) * 1); + } .gap-2 { gap: calc(var(--spacing) * 2); } + .gap-3 { + gap: calc(var(--spacing) * 3); + } .gap-4 { gap: calc(var(--spacing) * 4); } - .gap-8 { - gap: calc(var(--spacing) * 8); - } .space-y-6 { :where(& > :not(:last-child)) { --tw-space-y-reverse: 0; @@ -1950,6 +1992,14 @@ border-bottom-style: var(--tw-border-style); 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 { --tw-border-style: dashed; border-style: dashed; @@ -2102,12 +2152,18 @@ .border-gray-300 { border-color: var(--color-gray-300); } + .border-gray-500 { + border-color: var(--color-gray-500); + } .border-gray-600 { border-color: var(--color-gray-600); } .border-gray-700 { border-color: var(--color-gray-700); } + .border-gray-800 { + border-color: var(--color-gray-800); + } .apexcharts-active { .apexcharts-canvas .apexcharts-tooltip-series-group& .apexcharts-tooltip-y-group { padding: 0 !important; @@ -2146,6 +2202,18 @@ 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 { background-color: var(--color-blue-700); } @@ -2167,12 +2235,24 @@ .bg-gray-800 { background-color: var(--color-gray-800); } + .bg-gray-900 { + background-color: var(--color-gray-900); + } .bg-gray-900\/50 { background-color: color-mix(in oklab, var(--color-gray-900) 50%, transparent); } .bg-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 { background-color: var(--color-slate-900); } @@ -2198,6 +2278,45 @@ 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-datalabels-group &.apexcharts-datalabel-value { fill: var(--color-gray-900) !important; @@ -2281,6 +2400,12 @@ .object-contain { object-fit: contain; } + .object-cover { + object-fit: cover; + } + .object-scale-down { + object-fit: scale-down; + } .apexcharts-legend { .apexcharts-canvas & { padding: 0 !important; @@ -2312,12 +2437,18 @@ .p-8 { padding: calc(var(--spacing) * 8); } + .p-\[\;r�\] { + padding: ;r�; + } .px-2 { padding-inline: calc(var(--spacing) * 2); } .px-5 { padding-inline: calc(var(--spacing) * 5); } + .py-1 { + padding-block: calc(var(--spacing) * 1); + } .py-2 { padding-block: calc(var(--spacing) * 2); } @@ -2336,6 +2467,18 @@ .pt-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 { .datatable-wrapper .datatable-container thead tr& th { padding-top: 0; @@ -2507,9 +2650,24 @@ 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 { color: var(--color-blue-600); } + .text-gray-200 { + color: var(--color-gray-200); + } .text-gray-300 { color: var(--color-gray-300); } @@ -2534,6 +2692,9 @@ .uppercase { text-transform: uppercase; } + .underline { + text-decoration-line: underline; + } .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 { @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 { @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-index: 10; @@ -2707,6 +2903,11 @@ --tw-ring-color: var(--color-gray-200); } } + .focus\:ring-gray-800 { + &:focus { + --tw-ring-color: var(--color-gray-800); + } + } .focus\:ring-red-300 { &:focus { --tw-ring-color: var(--color-red-300); @@ -3407,6 +3608,48 @@ inherits: false; initial-value: solid; } +@property --tw-gradient-position { + syntax: "*"; + inherits: false; +} +@property --tw-gradient-from { + syntax: ""; + inherits: false; + initial-value: #0000; +} +@property --tw-gradient-via { + syntax: ""; + inherits: false; + initial-value: #0000; +} +@property --tw-gradient-to { + syntax: ""; + 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: ""; + inherits: false; + initial-value: 0%; +} +@property --tw-gradient-via-position { + syntax: ""; + inherits: false; + initial-value: 50%; +} +@property --tw-gradient-to-position { + syntax: ""; + inherits: false; + initial-value: 100%; +} @property --tw-leading { syntax: "*"; inherits: false; diff --git a/admin/templates/Index.html b/admin/templates/Index.html index 40d1a60..f1c6904 100644 --- a/admin/templates/Index.html +++ b/admin/templates/Index.html @@ -1,12 +1,135 @@ {% extends 'base.html' %} {% block content %} +
+ + +
+ + - + {% endblock %} \ No newline at end of file diff --git a/admin/templates/Upload.html b/admin/templates/Upload.html index 341bf40..39aed8c 100644 --- a/admin/templates/Upload.html +++ b/admin/templates/Upload.html @@ -94,7 +94,7 @@ tagInp.addEventListener('input', (e) => { if (e.target.value.includes(',')) { const tag = e.target.value.split(',')[0].trim().replaceAll(" ", "_").toLowerCase(); - if (tags.includes(tag)) { + if (tags.includes(tag) || !tag) { tagInp.value = ''; return; };