datatables api path & modal placeholder

This commit is contained in:
Corban-Lee Jones 2025-02-03 01:15:51 +00:00
parent 2a3ebd5b24
commit 88680f58a4
8 changed files with 502 additions and 55 deletions

View File

@ -799,6 +799,10 @@ select {
pointer-events: none;
}
.pointer-events-auto {
pointer-events: auto;
}
.invisible {
visibility: hidden;
}
@ -849,6 +853,10 @@ select {
inset-inline-end: 0px;
}
.end-3 {
inset-inline-end: 0.75rem;
}
.start-0 {
inset-inline-start: 0px;
}
@ -857,6 +865,10 @@ select {
top: 0px;
}
.top-1\/2 {
top: 50%;
}
.top-full {
top: 100%;
}
@ -877,10 +889,22 @@ select {
z-index: 60;
}
.z-\[80\] {
z-index: 80;
}
.-m-1\.5 {
margin: -0.375rem;
}
.m-3 {
margin: 0.75rem;
}
.m-4 {
margin: 1rem;
}
.mx-1 {
margin-left: 0.25rem;
margin-right: 0.25rem;
@ -906,6 +930,10 @@ select {
margin-bottom: 0.5rem;
}
.\!mb-0 {
margin-bottom: 0px !important;
}
.\!me-1 {
margin-inline-end: 0.25rem !important;
}
@ -1094,6 +1122,11 @@ select {
height: 60px;
}
.size-full {
width: 100%;
height: 100%;
}
.size-px {
width: 1px;
height: 1px;
@ -1107,6 +1140,10 @@ select {
height: 0.5rem;
}
.h-7 {
height: 1.75rem;
}
.h-\[32px\] {
height: 32px;
}
@ -1123,6 +1160,10 @@ select {
height: 100vh;
}
.max-h-72 {
max-height: 18rem;
}
.max-h-full {
max-height: 100%;
}
@ -1131,6 +1172,10 @@ select {
min-height: 400px;
}
.min-h-\[calc\(100\%-3\.5rem\)\] {
min-height: calc(100% - 3.5rem);
}
.\!w-2\.5 {
width: 0.625rem !important;
}
@ -1159,6 +1204,10 @@ select {
width: 26rem;
}
.w-\[3\.25rem\] {
width: 3.25rem;
}
.w-\[calc\(100\%-2rem\)\] {
width: calc(100% - 2rem);
}
@ -1179,10 +1228,6 @@ select {
min-width: 100%;
}
.max-w-\[100rem\] {
max-width: 100rem;
}
.max-w-\[300px\] {
max-width: 300px;
}
@ -1224,6 +1269,17 @@ select {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-95 {
--tw-scale-x: .95;
--tw-scale-y: .95;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@ -1262,6 +1318,10 @@ select {
flex-wrap: nowrap;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
@ -1382,6 +1442,10 @@ select {
overflow-y: auto;
}
.overflow-x-hidden {
overflow-x: hidden;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
@ -1579,6 +1643,10 @@ select {
padding: 1.5rem;
}
.p-px {
padding: 1px;
}
.\!py-0\.5 {
padding-top: 0.125rem !important;
padding-bottom: 0.125rem !important;
@ -1863,6 +1931,10 @@ select {
color: rgb(17 94 89 / var(--tw-text-opacity, 1));
}
.text-transparent {
color: transparent;
}
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
@ -1935,12 +2007,22 @@ select {
transition-duration: 150ms;
}
.transition-colors {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.transition-opacity {
transition-property: opacity;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.duration-200 {
transition-duration: 200ms;
}
.duration-300 {
transition-duration: 300ms;
}
@ -1949,6 +2031,10 @@ select {
transition-duration: 500ms;
}
.ease-in-out {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.\[--auto-close\:inside\] {
--auto-close: inside;
}
@ -2283,6 +2369,17 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
inset-inline-start: 0px;
}
.before\:inline-block::before {
content: var(--tw-content);
display: inline-block;
}
.before\:size-6::before {
content: var(--tw-content);
width: 1.5rem;
height: 1.5rem;
}
.before\:h-4::before {
content: var(--tw-content);
height: 1rem;
@ -2293,6 +2390,61 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
width: 100%;
}
.before\:translate-x-0::before {
content: var(--tw-content);
--tw-translate-x: 0px;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.before\:transform::before {
content: var(--tw-content);
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.before\:rounded-full::before {
content: var(--tw-content);
border-radius: 9999px;
}
.before\:bg-white::before {
content: var(--tw-content);
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.before\:shadow::before {
content: var(--tw-content);
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.before\:ring-0::before {
content: var(--tw-content);
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.before\:transition::before {
content: var(--tw-content);
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.before\:duration-200::before {
content: var(--tw-content);
transition-duration: 200ms;
}
.before\:ease-in-out::before {
content: var(--tw-content);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.after\:absolute::after {
content: var(--tw-content);
position: absolute;
@ -2318,6 +2470,32 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
width: 100%;
}
.checked\:border-blue-600:checked {
--tw-border-opacity: 1;
border-color: rgb(37 99 235 / var(--tw-border-opacity, 1));
}
.checked\:bg-none:checked {
background-image: none;
}
.checked\:text-blue-600:checked {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
}
.checked\:before\:translate-x-full:checked::before {
content: var(--tw-content);
--tw-translate-x: 100%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.checked\:before\:bg-blue-200:checked::before {
content: var(--tw-content);
--tw-bg-opacity: 1;
background-color: rgb(191 219 254 / var(--tw-bg-opacity, 1));
}
.hover\:bg-blue-700:hover {
--tw-bg-opacity: 1;
background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
@ -2328,6 +2506,11 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.hover\:bg-gray-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
}
.hover\:bg-gray-50:hover {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
@ -2363,6 +2546,11 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.focus\:bg-gray-200:focus {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
}
.focus\:bg-gray-50:focus {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
@ -2387,11 +2575,27 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
outline-offset: 2px;
}
.focus\:ring-2:focus {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-blue-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
}
.focus\:ring-blue-600:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(37 99 235 / var(--tw-ring-opacity, 1));
}
.focus\:checked\:border-blue-600:checked:focus {
--tw-border-opacity: 1;
border-color: rgb(37 99 235 / var(--tw-border-opacity, 1));
}
.disabled\:pointer-events-none:disabled {
pointer-events: none;
}
@ -2545,11 +2749,55 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.open.hs-overlay-open\:scale-100 {
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.open.hs-overlay-open\:opacity-100 {
opacity: 1;
}
.open .hs-overlay-open\:translate-x-0 {
--tw-translate-x: 0px;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.open .hs-overlay-open\:scale-100 {
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.open .hs-overlay-open\:opacity-100 {
opacity: 1;
}
.selected.hs-selected\:block {
display: block;
}
.selected .hs-selected\:block {
display: block;
}
.disabled.hs-select-disabled\:pointer-events-none {
pointer-events: none;
}
.disabled.hs-select-disabled\:opacity-50 {
opacity: 0.5;
}
.disabled .hs-select-disabled\:pointer-events-none {
pointer-events: none;
}
.disabled .hs-select-disabled\:opacity-50 {
opacity: 0.5;
}
.selected .hs-combo-box-selected\:block {
display: block;
}
@ -2605,6 +2853,10 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
grid-column: span 2 / span 2;
}
.sm\:m-6 {
margin: 1.5rem;
}
.sm\:block {
display: block;
}
@ -2613,14 +2865,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
display: inline;
}
.sm\:flex {
display: flex;
}
.sm\:hidden {
display: none;
}
.sm\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
@ -2629,18 +2873,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
flex-direction: row;
}
.sm\:items-center {
align-items: center;
}
.sm\:justify-end {
justify-content: flex-end;
}
.sm\:justify-between {
justify-content: space-between;
}
.sm\:gap-6 {
gap: 1.5rem;
}
@ -2650,15 +2882,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
column-gap: 0.75rem;
}
.sm\:gap-x-6 {
-moz-column-gap: 1.5rem;
column-gap: 1.5rem;
}
.sm\:gap-y-0 {
row-gap: 0px;
}
.sm\:space-y-6 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
@ -2678,11 +2901,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
padding-right: 1.5rem;
}
.sm\:py-0 {
padding-top: 0px;
padding-bottom: 0px;
}
.sm\:py-5 {
padding-top: 1.25rem;
padding-bottom: 1.25rem;
@ -2695,26 +2913,55 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
}
@media (min-width: 768px) {
.md\:mx-auto {
margin-left: auto;
margin-right: auto;
}
.md\:block {
display: block;
}
.md\:flex {
display: flex;
}
.md\:hidden {
display: none;
}
.md\:w-full {
width: 100%;
}
.md\:max-w-2xl {
max-width: 42rem;
}
.md\:grow {
flex-grow: 1;
}
.md\:flex-row {
flex-direction: row;
}
.md\:flex-nowrap {
flex-wrap: nowrap;
}
.md\:items-center {
align-items: center;
}
.md\:justify-start {
justify-content: flex-start;
}
.md\:justify-end {
justify-content: flex-end;
}
.md\:justify-between {
justify-content: space-between;
}
@ -2724,9 +2971,27 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
column-gap: 0.75rem;
}
.md\:gap-x-6 {
-moz-column-gap: 1.5rem;
column-gap: 1.5rem;
}
.md\:gap-y-0 {
row-gap: 0px;
}
.md\:p-5 {
padding: 1.25rem;
}
.md\:p-6 {
padding: 1.5rem;
}
.md\:py-0 {
padding-top: 0px;
padding-bottom: 0px;
}
}
@media (min-width: 1024px) {
@ -2926,6 +3191,11 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
color: rgb(115 115 115 / var(--tw-placeholder-opacity, 1));
}
.dark\:shadow-neutral-700\/70:where(.dark, .dark *) {
--tw-shadow-color: rgb(64 64 64 / 0.7);
--tw-shadow: var(--tw-shadow-colored);
}
.dark\:placeholder\:text-neutral-400:where(.dark, .dark *)::-moz-placeholder {
--tw-text-opacity: 1;
color: rgb(163 163 163 / var(--tw-text-opacity, 1));
@ -2936,6 +3206,12 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
color: rgb(163 163 163 / var(--tw-text-opacity, 1));
}
.dark\:before\:bg-neutral-400:where(.dark, .dark *)::before {
content: var(--tw-content);
--tw-bg-opacity: 1;
background-color: rgb(163 163 163 / var(--tw-bg-opacity, 1));
}
.dark\:checked\:border-blue-500:checked:where(.dark, .dark *) {
--tw-border-opacity: 1;
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
@ -2946,6 +3222,17 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
}
.dark\:checked\:before\:bg-blue-200:checked:where(.dark, .dark *)::before {
content: var(--tw-content);
--tw-bg-opacity: 1;
background-color: rgb(191 219 254 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:bg-neutral-600:hover:where(.dark, .dark *) {
--tw-bg-opacity: 1;
background-color: rgb(82 82 82 / var(--tw-bg-opacity, 1));
}
.dark\:hover\:bg-neutral-700:hover:where(.dark, .dark *) {
--tw-bg-opacity: 1;
background-color: rgb(64 64 64 / var(--tw-bg-opacity, 1));
@ -2976,6 +3263,11 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
color: rgb(115 115 115 / var(--tw-text-opacity, 1));
}
.dark\:focus\:bg-neutral-600:focus:where(.dark, .dark *) {
--tw-bg-opacity: 1;
background-color: rgb(82 82 82 / var(--tw-bg-opacity, 1));
}
.dark\:focus\:bg-neutral-700:focus:where(.dark, .dark *) {
--tw-bg-opacity: 1;
background-color: rgb(64 64 64 / var(--tw-bg-opacity, 1));
@ -3001,11 +3293,26 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
color: rgb(115 115 115 / var(--tw-text-opacity, 1));
}
.dark\:focus\:outline-none:focus:where(.dark, .dark *) {
outline: 2px solid transparent;
outline-offset: 2px;
}
.dark\:focus\:ring-1:focus:where(.dark, .dark *) {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.dark\:focus\:ring-neutral-600:focus:where(.dark, .dark *) {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(82 82 82 / var(--tw-ring-opacity, 1));
}
.dark\:focus\:ring-offset-gray-600:focus:where(.dark, .dark *) {
--tw-ring-offset-color: #4b5563;
}
.dark\:focus\:ring-offset-gray-800:focus:where(.dark, .dark *) {
--tw-ring-offset-color: #1f2937;
}

View File

@ -23,11 +23,21 @@
// console.log("Table redrawn")
// });
const formatTimestamp = timestamp => {
const d = new Date(timestamp.replace(" ", "T"));
const now = new Date();
// If younger than a year, show time
// otherwise show the year
return now - d < 31536000000
? `${d.getDate()} ${d.toLocaleString("en-GB", { month: "short" })}, ${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`
: `${d.getDate()} ${d.toLocaleString("en-GB", { month: "short" })}, ${d.getFullYear()}`;
}
const defineTable = () => {
new HSDataTable("#table", {
ajax: {
url: `/guild/${guild}/subscriptions/api`,
url: `/guild/${guild}/subscriptions/api/datatable`,
dataSrc: "data"
},
serverSide: true,
@ -108,7 +118,7 @@ const defineTable = () => {
render: (data, type, row) => {
return `
<td class="size-px whitespace-nowrap align-top">
<a href="${row.url}" class="block p-6 text-blue-500 hover:text-blue-600 focus:text-blue-600 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 text-nowrap">
<a href="${row.url}" class="block p-6 text-blue-500 hover:text-blue-600 focus:text-blue-600 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 text-nowrap" target="_blank">
${row.url}
</a>
</td>
@ -157,13 +167,12 @@ const defineTable = () => {
data: "created_at",
orderable: true,
searchable: true,
render: (data, type, row) => {
// 30th, Jan 2025
render: data => {
return `
<td class="size-px whitespace-nowrap align-top">
<div class="p-6">
<span class="text-sm text-gray-500 dark:text-neutral-500 text-nowrap">
${row.created_at}
${formatTimestamp(data)}
</span>
</div>
</td>

View File

@ -1,5 +1,5 @@
<nav class="bg-white dark:bg-neutral-900 border-b dark:border-none">
<div class="w-full mx-auto sm:flex sm:flex-row sm:justify-between sm:items-center sm:gap-x-3 py-3 sm:py-5 px-4 sm:px-6 lg:px-8">
<nav class="bg-white dark:bg-neutral-900 border dark:border-none m-4 sm:m-6 !mb-0 rounded-md">
<div class="w-full mx-auto md:flex md:flex-row md:justify-between md:items-center sm:gap-x-3 py-3 sm:py-5 px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center gap-x-3">
<div class="grow flex items-center gap-x-4">
<% if (guild.icon) { %>
@ -9,7 +9,7 @@
<span class="text-xs"><%= guild.name.split(" ").slice(0, 2).map(word => word[0].toUpperCase()).join(""); %></span>
</div>
<% } %>
<div class="d-flex items-center">
<div class="flex flex-col items-start">
<span class="font-semibold whitespace-nowrap text-2xl text-gray-800 dark:text-neutral-200">
<%= guild.name %>
</span>
@ -19,13 +19,13 @@
</div>
</div>
<button type="button" class="hs-collapse-toggle capitalize sm:hidden py-1.5 px-2 inline-flex items-center font-medium text-xs rounded-md border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 focus:outline-none focus:bg-gray-100 dark:border-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-collapse="#guildScreenDropdown">
<button type="button" class="hs-collapse-toggle capitalize md:hidden py-1.5 px-2 inline-flex items-center font-medium text-xs rounded-md border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 focus:outline-none focus:bg-gray-100 dark:border-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-collapse="#guildScreenDropdown">
<%= !isNaN(+guildPage) ? 'Overview' : guildPage %>
<svg class="hs-dropdown-open:rotate-180 shrink-0 size-4 ms-1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
<div id="guildScreenDropdown" class="hs-collapse hidden overflow-hidden transition-all duration-300 basis-full grow sm:block">
<div class="py-2 sm:py-0 flex flex-col sm:flex-row sm:justify-end gap-y-2 sm:gap-y-0 sm:gap-x-6">
<div id="guildScreenDropdown" class="hs-collapse hidden overflow-hidden transition-all duration-300 basis-full grow md:block">
<div class="py-2 md:py-0 flex flex-col md:flex-row md:justify-end gap-y-2 md:gap-y-0 md:gap-x-6">
<a href="/guild/<%= guild.id %>" class="guild-header-btn <%= !isNaN(+guildPage) ? 'active' : '' %>">Overview</a>
<a href="/guild/<%= guild.id %>/subscriptions" class="guild-header-btn <%= guildPage === 'subscriptions' ? 'active' : '' %>">Subscriptions</a>
<a href="/guild/<%= guild.id %>/filters" class="guild-header-btn <%= guildPage === 'filters' ? 'active' : '' %>">Filters</a>

View File

@ -3,7 +3,7 @@
<%- include("guildHeader") -%>
<!-- Card Section -->
<div class="max-w-[100rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
<div class="max-w-full p-4 md:p-6">
<!-- Grid -->
<div class="grid sm:grid-cols-2 xl:grid-cols-4 gap-4 sm:gap-6">
<!-- Card -->

View File

@ -60,13 +60,13 @@
</div>
</div>
<a class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none" href="#">
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none" data-hs-overlay="#hs-scale-animation-modal">
<svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
<span>
Add
<span class="hidden sm:inline">subscription</span>
</span>
</a>
</button>
</div>
</div>
@ -223,6 +223,125 @@
</div>
<!-- End Table Section -->
<!-- Popup -->
<div id="hs-scale-animation-modal" class="hs-overlay hidden size-full fixed top-0 start-0 z-[80] overflow-x-hidden overflow-y-auto pointer-events-none" role="dialog" tabindex="-1" aria-labelledby="hs-scale-animation-modal-label">
<div class="hs-overlay-animation-target hs-overlay-open:scale-100 hs-overlay-open:opacity-100 scale-95 opacity-0 ease-in-out transition-all duration-200 md:max-w-2xl md:w-full m-3 md:mx-auto min-h-[calc(100%-3.5rem)] flex items-center">
<div class="w-full flex flex-col bg-white border shadow-sm rounded-md pointer-events-auto dark:bg-neutral-800 dark:border-neutral-700 dark:shadow-neutral-700/70">
<div class="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
<h3 id="hs-scale-animation-modal-label" class="font-bold text-gray-800 dark:text-white">
Modal title
</h3>
<button type="button" class="size-8 inline-flex justify-center items-center gap-x-2 rounded-full border border-transparent bg-gray-100 text-gray-800 hover:bg-gray-200 focus:outline-none focus:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-700 dark:hover:bg-neutral-600 dark:text-neutral-400 dark:focus:bg-neutral-600" aria-label="Close" data-hs-overlay="#hs-scale-animation-modal">
<span class="sr-only">Close</span>
<svg class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
<div class="p-4 overflow-y-auto">
<div class="grid sm:grid-cols-2 gap-4 sm:gap-6">
<div>
<label for="" class="block text-sm font-medium mb-2 dark:text-white">Name</label>
<input type="text" class="py-3 px-4 block w-full border-gray-200 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Human-readable name for this entry.
</p>
</div>
<div>
<label for="" class="block text-sm font-medium mb-2 dark:text-white">URL</label>
<input type="url" class="py-3 px-4 block w-full border-gray-200 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Source of RSS content.
</p>
</div>
<div class="relative">
<label for="" class="block text-sm font-medium mb-2 dark:text-white">Message Style</label>
<select data-hs-select='{
"placeholder": "Select option...",
"toggleTag": "<button type=\"button\" aria-expanded=\"false\"></button>",
"toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-3 ps-4 pe-9 flex gap-x-2 text-nowrap w-full cursor-pointer bg-white border border-gray-200 rounded-lg text-start text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-neutral-600",
"dropdownScope": "window",
"dropdownClasses": "z-[80] w-full max-h-72 p-1 space-y-0.5 bg-white border border-gray-200 rounded-lg overflow-hidden overflow-y-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:border-neutral-700",
"optionClasses": "py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-none focus:bg-gray-100 hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800",
"optionTemplate": "<div class=\"flex justify-between items-center w-full\"><span data-title></span><span class=\"hidden hs-selected:block\"><svg class=\"shrink-0 size-3.5 text-blue-600 dark:text-blue-500 \" xmlns=\"http:.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span></div>",
"extraMarkup": "<div class=\"absolute top-1/2 end-3 -translate-y-1/2\"><svg class=\"shrink-0 size-3.5 text-gray-500 dark:text-neutral-500 \" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg></div>"
}' class="hidden">
<option value="">Choose</option>
<option>Default style</option>
</select>
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Appearance of delivered content.
</p>
</div>
<div>
<label for="" class="block text-sm font-medium mb-2 dark:text-white">Published Threshold</label>
<input type="datetime-local" class="py-3 px-4 block w-full border-gray-200 rounded-md text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600">
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Ignore content older than this date.
</p>
</div>
<div class="relative">
<label for="" class="block text-sm font-medium mb-2 dark:text-white">Channels</label>
<select data-hs-select='{
"placeholder": "Select option...",
"toggleTag": "<button type=\"button\" aria-expanded=\"false\"></button>",
"toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-3 ps-4 pe-9 flex gap-x-2 text-nowrap w-full cursor-pointer bg-white border border-gray-200 rounded-lg text-start text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-neutral-600",
"dropdownScope": "window",
"dropdownClasses": "z-[80] w-full max-h-72 p-1 space-y-0.5 bg-white border border-gray-200 rounded-lg overflow-hidden overflow-y-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:border-neutral-700",
"optionClasses": "py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-none focus:bg-gray-100 hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800",
"optionTemplate": "<div class=\"flex justify-between items-center w-full\"><span data-title></span><span class=\"hidden hs-selected:block\"><svg class=\"shrink-0 size-3.5 text-blue-600 dark:text-blue-500 \" xmlns=\"http:.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span></div>",
"extraMarkup": "<div class=\"absolute top-1/2 end-3 -translate-y-1/2\"><svg class=\"shrink-0 size-3.5 text-gray-500 dark:text-neutral-500 \" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg></div>"
}' class="hidden">
<option value="">Choose</option>
<option>#general</option>
<option>#news</option>
<option>#admin</option>
</select>
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Ignore content older than this date.
</p>
</div>
<div class="relative">
<label for="" class="block text-sm font-medium mb-2 dark:text-white">Filters</label>
<select data-hs-select='{
"placeholder": "Select option...",
"toggleTag": "<button type=\"button\" aria-expanded=\"false\"></button>",
"toggleClasses": "hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-3 ps-4 pe-9 flex gap-x-2 text-nowrap w-full cursor-pointer bg-white border border-gray-200 rounded-lg text-start text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-neutral-600",
"dropdownScope": "window",
"dropdownClasses": "z-[80] w-full max-h-72 p-1 space-y-0.5 bg-white border border-gray-200 rounded-lg overflow-hidden overflow-y-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:border-neutral-700",
"optionClasses": "py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-lg focus:outline-none focus:bg-gray-100 hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800",
"optionTemplate": "<div class=\"flex justify-between items-center w-full\"><span data-title></span><span class=\"hidden hs-selected:block\"><svg class=\"shrink-0 size-3.5 text-blue-600 dark:text-blue-500 \" xmlns=\"http:.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span></div>",
"extraMarkup": "<div class=\"absolute top-1/2 end-3 -translate-y-1/2\"><svg class=\"shrink-0 size-3.5 text-gray-500 dark:text-neutral-500 \" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m7 15 5 5 5-5\"/><path d=\"m7 9 5-5 5 5\"/></svg></div>"
}' class="hidden">
<option value="">Choose</option>
<option>Filter 1</option>
<option>Filter 2</option>
<option>Filter 3</option>
</select>
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
Ignore content older than this date.
</p>
</div>
<div class="flex items-center">
<input type="checkbox" id="hs-basic-with-description-unchecked" class="relative w-[3.25rem] h-7 p-px bg-gray-100 border-transparent text-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:ring-blue-600 disabled:opacity-50 disabled:pointer-events-none checked:bg-none checked:text-blue-600 checked:border-blue-600 focus:checked:border-blue-600 dark:bg-neutral-800 dark:border-neutral-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-600 before:inline-block before:size-6 before:bg-white checked:before:bg-blue-200 before:translate-x-0 checked:before:translate-x-full before:rounded-full before:shadow before:transform before:ring-0 before:transition before:ease-in-out before:duration-200 dark:before:bg-neutral-400 dark:checked:before:bg-blue-200">
<label for="hs-basic-with-description-unchecked" class="text-sm text-gray-500 ms-3 dark:text-neutral-400">Enabled</label>
</div>
</div>
</div>
<div class="flex justify-end items-center gap-x-2 py-3 px-4 border-t dark:border-neutral-700">
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-overlay="#hs-scale-animation-modal">
Close
</button>
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
Save changes
</button>
</div>
</div>
</div>
</div>
<!-- End Popup -->
<script>var guild = "<%- guild %>"</script>
<% block("scripts").append('<script defer src="/static/js/guild/subscriptions.js"></script>'); %>

View File

@ -18,6 +18,7 @@
<script src="/static/foreign/jquery.js"></script>
<script src="/static/foreign/dataTables.js"></script>
<script src="/static/foreign/popper.js"></script>
<script src="/static/foreign/preline.js"></script>
<script src="/static/js/main.js"></script>
<%- block("scripts").toString() %>

View File

@ -1,7 +1,7 @@
import { Request, Response } from "express";
import { buildDatatableQuery } from "@utils/datatable";
export const get = async (request: Request, response: Response) => {
export const datatable = async (request: Request, response: Response) => {
try {
const { query, recordsTotal, recordsFiltered } = await buildDatatableQuery(
request as any,
@ -18,7 +18,17 @@ export const get = async (request: Request, response: Response) => {
}
catch (error) {
console.error(error);
response.status(500).json({ error: "Failed to fetch subscriptions" });
response.status(500).json({ error: "Failed to fetch datatable for subscriptions" });
}
}
export const get = async (request: Request, response: Response) => {
try {
//
}
catch (error) {
console.error(error);
response.status(500).json({ error: "Failed to fetch subscription" });
}
}
@ -32,4 +42,4 @@ export const post = async (request: Request, response: Response) => {
}
}
export default { get, post }
export default { datatable, get, post }

View File

@ -3,6 +3,7 @@ import { Router } from "express";
import subApiController from "@server/controllers/guild/sub.api.controller";
const router = Router();
router.get("/:guildId/subscriptions/api/datatable", subApiController.datatable);
router.get("/:guildId/subscriptions/api", subApiController.get);
router.post("/:guildId/subscriptions/api", subApiController.post);