Overhaul design
This commit is contained in:
parent
3fd7539d7f
commit
5eb26c3b53
29
app/http/endpoints/api/guild.go
Normal file
29
app/http/endpoints/api/guild.go
Normal file
@ -0,0 +1,29 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/TicketsBot/GoPanel/botcontext"
|
||||
"github.com/TicketsBot/GoPanel/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func GuildHandler(ctx *gin.Context) {
|
||||
guildId := ctx.Keys["guildid"].(uint64)
|
||||
|
||||
botContext, err := botcontext.ContextForGuild(guildId)
|
||||
if err != nil {
|
||||
ctx.JSON(500, utils.ErrorJson(err))
|
||||
return
|
||||
}
|
||||
|
||||
guild, err := botContext.GetGuild(ctx, guildId)
|
||||
if err != nil {
|
||||
ctx.JSON(500, utils.ErrorJson(err))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, gin.H{
|
||||
"id": guild.Id,
|
||||
"name": guild.Name,
|
||||
"icon": guild.Icon,
|
||||
})
|
||||
}
|
@ -94,6 +94,7 @@ func StartServer(sm *livechat.SocketManager) {
|
||||
guildAuthApiSupport := apiGroup.Group("/:id", middleware.AuthenticateGuild(permission.Support))
|
||||
guildApiNoAuth := apiGroup.Group("/:id", middleware.ParseGuildId)
|
||||
{
|
||||
guildAuthApiSupport.GET("/guild", api.GuildHandler)
|
||||
guildAuthApiSupport.GET("/channels", api.ChannelsHandler)
|
||||
guildAuthApiSupport.GET("/premium", api.PremiumHandler)
|
||||
guildAuthApiSupport.GET("/user/:user", api.UserHandler)
|
||||
|
@ -1,4 +1,10 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
|
||||
|
||||
:root {
|
||||
--primary: #995DF3;
|
||||
--primary-gradient: linear-gradient(71.3deg, #873ef5 0%, #995DF3 100%);
|
||||
--blue: #3472f7;
|
||||
}
|
||||
|
||||
html, body {
|
||||
position: relative;
|
||||
@ -7,7 +13,7 @@ html, body {
|
||||
}
|
||||
|
||||
body, h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6, p, .navbar, .brand, .btn-simple, .alert, a, .td-name, td, button.close {
|
||||
font-family: 'Noto Sans', sans-serif !important;
|
||||
font-family: 'Poppins', sans-serif !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
export let colour = '#3472f7';
|
||||
export let colour = '';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -11,7 +11,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
background-color: var(--badge-background-color, #3472f7);
|
||||
background: var(--badge-background-color, var(--primary));
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
padding: 0 4px;
|
||||
|
@ -28,9 +28,10 @@
|
||||
text-align: center;
|
||||
|
||||
color: white;
|
||||
background-color: #3472f7;
|
||||
border-color: #3472f7;
|
||||
border-width: 2px;
|
||||
background: var(--primary-gradient);
|
||||
border: none;
|
||||
/*border-color: var(--primary);*/
|
||||
/*border-width: 2px;*/
|
||||
border-radius: .25rem;
|
||||
margin: 0;
|
||||
|
||||
@ -39,14 +40,14 @@
|
||||
box-shadow: 0 4px 4px rgb(0 0 0 / 25%);
|
||||
}
|
||||
|
||||
button:active, button:hover:enabled {
|
||||
background-color: #0062cc;
|
||||
border-color: #0062cc;
|
||||
}
|
||||
/*button:active, button:hover:enabled {*/
|
||||
/* background-color: #0062cc;*/
|
||||
/* border-color: #0062cc;*/
|
||||
/*}*/
|
||||
|
||||
button:disabled {
|
||||
background-color: #6c757d;
|
||||
border-color: #6c757d;
|
||||
background: #6c757d;
|
||||
border: #6c757d;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@ -60,12 +61,12 @@
|
||||
}
|
||||
|
||||
.danger {
|
||||
background-color: #dc3545 !important;
|
||||
background: #dc3545 !important;
|
||||
border-color: #dc3545 !important;
|
||||
}
|
||||
|
||||
.danger:hover:enabled, .danger:active {
|
||||
background-color: #c32232 !important;
|
||||
background: #c32232 !important;
|
||||
border-color: #c32232 !important;
|
||||
}
|
||||
|
||||
|
136
frontend/src/includes/ManageSidebar.svelte
Normal file
136
frontend/src/includes/ManageSidebar.svelte
Normal file
@ -0,0 +1,136 @@
|
||||
<section class="sidebar">
|
||||
<header>
|
||||
<img src="{getIconUrl()}" class="guild-icon" alt="Guild icon" width="50" height="50"/>
|
||||
{guild.name}
|
||||
</header>
|
||||
<nav>
|
||||
<ul class="nav-list">
|
||||
<ManageSidebarLink {currentRoute} title="← Back to servers" href="/" />
|
||||
|
||||
{#if isAdmin}
|
||||
<ManageSidebarLink {currentRoute} title="Settings" icon="fa-cogs" href="/manage/{guildId}/settings" />
|
||||
{/if}
|
||||
|
||||
<ManageSidebarLink {currentRoute} title="Transcripts" icon="fa-copy" href="/manage/{guildId}/transcripts" />
|
||||
|
||||
{#if isAdmin}
|
||||
<ManageSidebarLink {currentRoute} routePrefix="/manage/{guildId}/panels" title="Ticket Panels" icon="fa-mouse-pointer" href="/manage/{guildId}/panels" />
|
||||
|
||||
<ManageSidebarLink {currentRoute} title="Forms" icon="fa-poll-h" href="/manage/{guildId}/forms" />
|
||||
<ManageSidebarLink {currentRoute} title="Staff Teams" icon="fa-users" href="/manage/{guildId}/teams" />
|
||||
<ManageSidebarLink {currentRoute} title="Integrations" icon="fa-robot" href="/manage/{guildId}/integrations" />
|
||||
{/if}
|
||||
|
||||
<ManageSidebarLink {currentRoute} title="Tickets" icon="fa-ticket-alt" href="/manage/{guildId}/tickets" />
|
||||
<ManageSidebarLink {currentRoute} title="Blacklist" icon="fa-ban" href="/manage/{guildId}/blacklist" />
|
||||
<ManageSidebarLink {currentRoute} title="Tags" icon="fa-tags" href="/manage/{guildId}/tags" />
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="bottom">
|
||||
<hr/>
|
||||
<ul class="nav-list">
|
||||
<ManageSidebarLink {currentRoute} title="Documentation" icon="fa-book" href="https://docs.ticketsbot.net" newWindow />
|
||||
<ManageSidebarLink {currentRoute} title="Logout" icon="fa-sign-out-alt" href="/logout" />
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
background-color: #272727;
|
||||
padding: 15px;
|
||||
width: 275px;
|
||||
border-radius: 6px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
font-weight: bold;
|
||||
|
||||
padding: 6px 10px;
|
||||
border-radius: 4px;
|
||||
|
||||
background: linear-gradient(33.3deg, #873ef5 0%, #995DF3 100%);
|
||||
box-shadow: 0 6px 6px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
|
||||
}
|
||||
|
||||
.guild-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
nav > ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav hr {
|
||||
width: 40%;
|
||||
padding-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import {onMount} from "svelte";
|
||||
import axios from "axios";
|
||||
import {API_URL} from "../js/constants";
|
||||
import {notifyError, withLoadingScreen} from "../js/util";
|
||||
import ManageSidebarLink from "./ManageSidebarLink.svelte";
|
||||
import SubNavigation from "./SubNavigation.svelte";
|
||||
import SubNavigationLink from "./SubNavigationLink.svelte";
|
||||
|
||||
export let currentRoute;
|
||||
export let permissionLevel;
|
||||
|
||||
$: isAdmin = permissionLevel >= 2;
|
||||
|
||||
let guildId = currentRoute.namedParams.id;
|
||||
|
||||
let guild = {};
|
||||
|
||||
async function loadGuild() {
|
||||
const res = await axios.get(`${API_URL}/api/${guildId}/guild`);
|
||||
if (res.status !== 200) {
|
||||
notifyError(res.data.error);
|
||||
return;
|
||||
}
|
||||
|
||||
guild = res.data;
|
||||
}
|
||||
|
||||
function isAnimated() {
|
||||
if (guild.icon === undefined || guild.icon === "") {
|
||||
return false;
|
||||
} else {
|
||||
return guild.icon.startsWith('a_')
|
||||
}
|
||||
}
|
||||
|
||||
function getIconUrl() {
|
||||
if (!guild.icon) {
|
||||
return `https://cdn.discordapp.com/embed/avatars/${Number((BigInt(guildId) >> BigInt(22)) % BigInt(6))}.png`
|
||||
}
|
||||
|
||||
if (isAnimated()) {
|
||||
return `https:\/\/cdn.discordapp.com/icons/${guild.id}/${guild.icon}.gif?size=256`
|
||||
} else {
|
||||
return `https:\/\/cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp?size=256`
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await withLoadingScreen(async () => {
|
||||
await loadGuild();
|
||||
})
|
||||
});
|
||||
</script>
|
52
frontend/src/includes/ManageSidebarLink.svelte
Normal file
52
frontend/src/includes/ManageSidebarLink.svelte
Normal file
@ -0,0 +1,52 @@
|
||||
<li>
|
||||
<div style="width: 100%">
|
||||
<a href="{href}" class:active target="{newWindow === true ? '_blank' : '_self'}">
|
||||
{#if icon}
|
||||
<i class="fas {icon}"/>
|
||||
{/if}
|
||||
|
||||
<span>{title}</span>
|
||||
</a>
|
||||
|
||||
{#if active}
|
||||
<slot/>
|
||||
{/if}
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<style>
|
||||
a.active {
|
||||
background: linear-gradient(71.3deg, #873ef5 0%, #995DF3 100%);
|
||||
box-shadow: 0 6px 6px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
|
||||
}
|
||||
|
||||
a, a:link, a:hover, a:visited, a:active {
|
||||
display: block;
|
||||
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
font-size: 16px;
|
||||
padding: 5px 10px 5px 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
i {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export let currentRoute;
|
||||
export let title;
|
||||
export let icon;
|
||||
export let href = "#";
|
||||
export let routePrefix;
|
||||
export let newWindow;
|
||||
|
||||
let active = href !== "/" && ((routePrefix || href)?.toLowerCase() === currentRoute.name.toLowerCase() ||
|
||||
currentRoute.name.toLowerCase().startsWith((routePrefix || href).toLowerCase()));
|
||||
|
||||
$: active;
|
||||
</script>
|
@ -19,12 +19,7 @@
|
||||
<NavElement icon="fas fa-mouse-pointer" link="/manage/{guildId}/panels" on:click={closeDropdown}>Ticket Panels</NavElement>
|
||||
<NavElement icon="fas fa-poll-h" link="/manage/{guildId}/forms" on:click={closeDropdown}>Forms</NavElement>
|
||||
<NavElement icon="fas fa-users" link="/manage/{guildId}/teams" on:click={closeDropdown}>Staff Teams</NavElement>
|
||||
<NavElement icon="fas fa-robot" link="/manage/{guildId}/integrations" on:click={closeDropdown}>
|
||||
<div style="display: flex; gap:4px">
|
||||
Integrations
|
||||
<Badge>New!</Badge>
|
||||
</div>
|
||||
</NavElement>
|
||||
<NavElement icon="fas fa-robot" link="/manage/{guildId}/integrations" on:click={closeDropdown}>Integrations</NavElement>
|
||||
{/if}
|
||||
|
||||
<NavElement icon="fas fa-ticket-alt" link="/manage/{guildId}/tickets" on:click={closeDropdown}>Tickets</NavElement>
|
||||
@ -63,7 +58,7 @@
|
||||
|
||||
<style>
|
||||
.navbar {
|
||||
display: flex;
|
||||
display: none;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
background-color: #272727;
|
||||
@ -89,6 +84,10 @@
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1154px) {
|
||||
.navbar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-section {
|
||||
display: none;
|
||||
}
|
||||
|
19
frontend/src/includes/SubNavigation.svelte
Normal file
19
frontend/src/includes/SubNavigation.svelte
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="root">
|
||||
<ul>
|
||||
<slot/>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
ul {
|
||||
width: 100%;
|
||||
list-style-type: none;
|
||||
margin: 2px 0 0 55px;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
53
frontend/src/includes/SubNavigationLink.svelte
Normal file
53
frontend/src/includes/SubNavigationLink.svelte
Normal file
@ -0,0 +1,53 @@
|
||||
<li>
|
||||
<div class="wrapper">
|
||||
<a href="{href}" class:active>
|
||||
{#if icon}
|
||||
<i class="fas {icon}"/>
|
||||
{/if}
|
||||
|
||||
<span>
|
||||
<slot/>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<style>
|
||||
li {
|
||||
/*padding: 2px 0;*/
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a.active {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
a:not(.active) {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
a, a:link, a:hover, a:visited, a:active {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
i {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export let currentRoute;
|
||||
export let icon;
|
||||
export let href = "#";
|
||||
export let routePrefix;
|
||||
|
||||
let active = href !== "/" && ((routePrefix || href).toLowerCase() === currentRoute.name.toLowerCase() ||
|
||||
currentRoute.name.toLowerCase().startsWith((routePrefix || href).toLowerCase()));
|
||||
|
||||
$: active;
|
||||
</script>
|
@ -5,6 +5,7 @@
|
||||
<div class="super-container" class:dropdown={$dropdown}>
|
||||
<LoadingScreen/>
|
||||
<div class="content-container" class:hide={$loadingScreen}>
|
||||
<ManageSidebar {currentRoute} {permissionLevel} />
|
||||
<Route {currentRoute} {params}/>
|
||||
</div>
|
||||
<NotifyModal/>
|
||||
@ -23,8 +24,13 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.super-container {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -48,6 +54,7 @@
|
||||
import {setDefaultHeaders} from '../includes/Auth.svelte'
|
||||
import {permissionLevelCache} from '../js/stores';
|
||||
import {get} from 'svelte/store';
|
||||
import ManageSidebar from "../includes/ManageSidebar.svelte";
|
||||
|
||||
export let currentRoute;
|
||||
export let params = {};
|
||||
|
@ -1,141 +1,141 @@
|
||||
{#if blacklistUserModal}
|
||||
<div class="modal" transition:fade>
|
||||
<div class="modal-wrapper">
|
||||
<Card footer footerRight fill={false}>
|
||||
<span slot="title">Blacklist User</span>
|
||||
<div class="modal" transition:fade>
|
||||
<div class="modal-wrapper">
|
||||
<Card footer footerRight fill={false}>
|
||||
<span slot="title">Blacklist User</span>
|
||||
|
||||
<div slot="body" class="modal-inner">
|
||||
<div>
|
||||
<label class="form-label" style="margin-bottom: 0 !important;">Use User ID</label>
|
||||
<Toggle hideLabel
|
||||
toggledColor="#66bb6a"
|
||||
untoggledColor="#ccc"
|
||||
bind:toggled={blacklistById}/>
|
||||
</div>
|
||||
<div slot="body" class="modal-inner">
|
||||
<div>
|
||||
<label class="form-label" style="margin-bottom: 0 !important;">Use User ID</label>
|
||||
<Toggle hideLabel
|
||||
toggledColor="#66bb6a"
|
||||
untoggledColor="#ccc"
|
||||
bind:toggled={blacklistById}/>
|
||||
</div>
|
||||
|
||||
{#if blacklistById}
|
||||
<Input label="User ID" placeholder="592348585904198711" bind:value={blacklistUserId}/>
|
||||
{:else}
|
||||
<div class="user-select-wrapper">
|
||||
<UserSelect {guildId} label="User" bind:value={blacklistUser} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if blacklistById}
|
||||
<Input label="User ID" placeholder="592348585904198711" bind:value={blacklistUserId}/>
|
||||
{:else}
|
||||
<div class="user-select-wrapper">
|
||||
<UserSelect {guildId} label="User" bind:value={blacklistUser}/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div slot="footer" style="gap: 12px">
|
||||
<Button danger on:click={() => blacklistUserModal = false}>Cancel</Button>
|
||||
<Button on:click={addUser}>Confirm</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div slot="footer" style="gap: 12px">
|
||||
<Button danger on:click={() => blacklistUserModal = false}>Cancel</Button>
|
||||
<Button on:click={addUser}>Confirm</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" transition:fade>
|
||||
</div>
|
||||
<div class="modal-backdrop" transition:fade>
|
||||
</div>
|
||||
{:else if blacklistRoleModal}
|
||||
<div class="modal" transition:fade>
|
||||
<div class="modal-wrapper">
|
||||
<Card footer footerRight fill={false}>
|
||||
<span slot="title">Blacklist Role</span>
|
||||
<div class="modal" transition:fade>
|
||||
<div class="modal-wrapper">
|
||||
<Card footer footerRight fill={false}>
|
||||
<span slot="title">Blacklist Role</span>
|
||||
|
||||
<div slot="body" class="modal-inner user-select-wrapper">
|
||||
<RoleSelect {guildId} {roles} label="Role" bind:value={blacklistRole} />
|
||||
</div>
|
||||
<div slot="body" class="modal-inner user-select-wrapper">
|
||||
<RoleSelect {guildId} {roles} label="Role" bind:value={blacklistRole}/>
|
||||
</div>
|
||||
|
||||
<div slot="footer" style="gap: 12px">
|
||||
<Button danger on:click={() => blacklistRoleModal = false}>Cancel</Button>
|
||||
<Button on:click={addRole}>Confirm</Button>
|
||||
<div slot="footer" style="gap: 12px">
|
||||
<Button danger on:click={() => blacklistRoleModal = false}>Cancel</Button>
|
||||
<Button on:click={addRole}>Confirm</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop" transition:fade>
|
||||
</div>
|
||||
<div class="modal-backdrop" transition:fade>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if data}
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<div class="main-col">
|
||||
<Card footer={false}>
|
||||
<span slot="title">Blacklist</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<div class="row" style="gap: 10px">
|
||||
<Button icon="fas fa-ban" on:click={() => blacklistUserModal = true}>Blacklist New User</Button>
|
||||
<Button icon="fas fa-ban" on:click={() => blacklistRoleModal = true}>Blacklist New Role</Button>
|
||||
</div>
|
||||
<div class="main-col">
|
||||
<Card footer={false}>
|
||||
<span slot="title">Blacklist</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<div class="row" style="gap: 10px">
|
||||
<Button icon="fas fa-ban" on:click={() => blacklistUserModal = true}>Blacklist New User</Button>
|
||||
<Button icon="fas fa-ban" on:click={() => blacklistRoleModal = true}>Blacklist New Role</Button>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<hr/>
|
||||
|
||||
<div class="tables">
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="full-width">Role</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.roles as roleId}
|
||||
{@const role = roles.find(role => role.id === roleId)}
|
||||
<tr>
|
||||
{#if role === undefined}
|
||||
<td class="full-width">Unknown ({roleId})</td>
|
||||
{:else}
|
||||
<td class="full-width">{role.name}</td>
|
||||
{/if}
|
||||
<div class="tables">
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="full-width">Role</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.roles as roleId}
|
||||
{@const role = roles.find(role => role.id === roleId)}
|
||||
<tr>
|
||||
{#if role === undefined}
|
||||
<td class="full-width">Unknown ({roleId})</td>
|
||||
{:else}
|
||||
<td class="full-width">{role.name}</td>
|
||||
{/if}
|
||||
|
||||
<td>
|
||||
<Button type="button" danger icon="fas fa-trash-can" on:click={() => removeRoleBlacklist(roleId, role)}>
|
||||
Remove
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<td>
|
||||
<Button type="button" danger icon="fas fa-trash-can"
|
||||
on:click={() => removeRoleBlacklist(roleId, role)}>
|
||||
Remove
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="full-width">User</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.users as user}
|
||||
<tr>
|
||||
{#if user.username !== ''}
|
||||
<td class="full-width">{user.username} ({user.id})</td>
|
||||
{:else}
|
||||
<td class="full-width">Unknown ({user.id})</td>
|
||||
{/if}
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="full-width">User</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.users as user}
|
||||
<tr>
|
||||
{#if user.username !== ''}
|
||||
<td class="full-width">{user.username} ({user.id})</td>
|
||||
{:else}
|
||||
<td class="full-width">Unknown ({user.id})</td>
|
||||
{/if}
|
||||
|
||||
<td>
|
||||
<Button type="button" danger icon="fas fa-trash-can" on:click={() => removeUserBlacklist(user)}>
|
||||
Remove
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<td>
|
||||
<Button type="button" danger icon="fas fa-trash-can"
|
||||
on:click={() => removeUserBlacklist(user)}>
|
||||
Remove
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="row nav">
|
||||
<i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page <= 1}
|
||||
on:click={loadPrevious}></i>
|
||||
<span>Page {page}</span>
|
||||
<i class="fas fa-chevron-right pagination-chevron"
|
||||
class:disabled-chevron={data.users.length < data.page_limit && data.roles.length < data.page_limit}
|
||||
on:click={loadNext}></i>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="row nav">
|
||||
<i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page <= 1}
|
||||
on:click={loadPrevious}></i>
|
||||
<span>Page {page}</span>
|
||||
<i class="fas fa-chevron-right pagination-chevron"
|
||||
class:disabled-chevron={data.users.length < data.page_limit && data.roles.length < data.page_limit}
|
||||
on:click={loadNext}></i>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<script>
|
||||
@ -296,21 +296,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-left: 2%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 60%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
padding-bottom: 4%;
|
||||
}
|
||||
|
||||
.main-col {
|
||||
@ -359,6 +348,7 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.pagination-chevron {
|
||||
|
@ -1,83 +1,84 @@
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<div class="content">
|
||||
<Card footer footerRight>
|
||||
<span slot="title">Forms</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<div class="section">
|
||||
<h2 class="section-title">Create New Form</h2>
|
||||
<span slot="title">Forms</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<div class="section">
|
||||
<h2 class="section-title">Create New Form</h2>
|
||||
|
||||
<form on:submit|preventDefault={createForm}>
|
||||
<div class="row" id="creation-row">
|
||||
<Input placeholder="Form Title" col3={true} bind:value={newTitle}/>
|
||||
<div id="create-button-wrapper">
|
||||
<Button icon="fas fa-paper-plane" fullWidth={windowWidth <= 950}>Create</Button>
|
||||
</div>
|
||||
<form on:submit|preventDefault={createForm}>
|
||||
<div class="row" id="creation-row">
|
||||
<Input placeholder="Form Title" col3={true} bind:value={newTitle}/>
|
||||
<div id="create-button-wrapper">
|
||||
<Button icon="fas fa-paper-plane" fullWidth={windowWidth <= 950}>Create</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2 class="section-title">Manage Forms</h2>
|
||||
<div class="section">
|
||||
<h2 class="section-title">Manage Forms</h2>
|
||||
|
||||
{#if editingTitle && activeFormId !== null}
|
||||
<div class="row form-name-edit-wrapper">
|
||||
<Input col4 label="Form Title" placeholder="Form Title" bind:value={renamedTitle}/>
|
||||
<div class="form-name-save-wrapper">
|
||||
<Button icon="fas fa-floppy-disk" fullWidth={windowWidth <= 950} on:click={updateTitle}>Save</Button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="row form-select-row">
|
||||
<div class="multiselect-super">
|
||||
<Dropdown col1 bind:value={activeFormId}>
|
||||
<option value={null}>Select a form...</option>
|
||||
{#each forms as form}
|
||||
<option value="{form.form_id}">{form.title}</option>
|
||||
{/each}
|
||||
</Dropdown>
|
||||
</div>
|
||||
{#if editingTitle && activeFormId !== null}
|
||||
<div class="row form-name-edit-wrapper">
|
||||
<Input col4 label="Form Title" placeholder="Form Title" bind:value={renamedTitle}/>
|
||||
<div class="form-name-save-wrapper">
|
||||
<Button icon="fas fa-floppy-disk" fullWidth={windowWidth <= 950} on:click={updateTitle}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="row form-select-row">
|
||||
<div class="multiselect-super">
|
||||
<Dropdown col1 bind:value={activeFormId}>
|
||||
<option value={null}>Select a form...</option>
|
||||
{#each forms as form}
|
||||
<option value="{form.form_id}">{form.title}</option>
|
||||
{/each}
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
{#if activeFormId !== null}
|
||||
<Button on:click={() => editingTitle = true}>Rename Form</Button>
|
||||
<Button danger type="button"
|
||||
on:click={() => deleteForm(activeFormId)}>Delete {activeFormTitle}</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if activeFormId !== null}
|
||||
<Button on:click={() => editingTitle = true}>Rename Form</Button>
|
||||
<Button danger type="button"
|
||||
on:click={() => deleteForm(activeFormId)}>Delete {activeFormTitle}</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="manage">
|
||||
{#if activeFormId !== null}
|
||||
{#each forms.find(form => form.form_id === activeFormId).inputs as input, i (input)}
|
||||
<div animate:flip="{{duration: 500}}">
|
||||
<FormInputRow data={input} formId={activeFormId}
|
||||
withSaveButton={true} withDeleteButton={true} withDirectionButtons={true}
|
||||
index={i} {formLength}
|
||||
on:delete={() => deleteInput(activeFormId, input)}
|
||||
on:move={(e) => changePosition(activeFormId, input, e.detail.direction)}/>
|
||||
<div class="manage">
|
||||
{#if activeFormId !== null}
|
||||
{#each forms.find(form => form.form_id === activeFormId).inputs as input, i (input)}
|
||||
<div animate:flip="{{duration: 500}}">
|
||||
<FormInputRow data={input} formId={activeFormId}
|
||||
withSaveButton={true} withDeleteButton={true} withDirectionButtons={true}
|
||||
index={i} {formLength}
|
||||
on:delete={() => deleteInput(activeFormId, input)}
|
||||
on:move={(e) => changePosition(activeFormId, input, e.detail.direction)}/>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if activeFormId !== null}
|
||||
<div class="row"
|
||||
style="justify-content: center; align-items: center; gap: 10px; margin-top: 10px">
|
||||
<hr class="fill">
|
||||
<div class="row add-input-container" class:add-input-disabled={formLength >= 5}>
|
||||
<i class="fas fa-plus"></i>
|
||||
<a on:click={addInput}>New Field</a>
|
||||
</div>
|
||||
<hr class="fill">
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if activeFormId !== null}
|
||||
<div class="row" style="justify-content: center; align-items: center; gap: 10px; margin-top: 10px">
|
||||
<hr class="fill">
|
||||
<div class="row add-input-container" class:add-input-disabled={formLength >= 5}>
|
||||
<i class="fas fa-plus"></i>
|
||||
<a on:click={addInput}>New Field</a>
|
||||
</div>
|
||||
<hr class="fill">
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<Button type="submit" icon="fas fa-floppy-disk" disabled={formLength === 0} on:click={saveInputs}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="submit" icon="fas fa-floppy-disk" disabled={formLength === 0} on:click={saveInputs}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svelte:window bind:innerWidth={windowWidth}/>
|
||||
@ -282,20 +283,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.body-wrapper {
|
||||
@ -383,7 +374,7 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-input-disabled > *{
|
||||
.add-input-disabled > * {
|
||||
cursor: default !important;
|
||||
color: #777 !important;
|
||||
}
|
||||
|
@ -19,8 +19,6 @@
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0 45px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.main-col {
|
||||
@ -28,7 +26,6 @@
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.right-col {
|
||||
|
@ -1,41 +1,37 @@
|
||||
{#if tagCreateModal}
|
||||
<TagEditor {isPremium} on:cancel={() => tagCreateModal = false} on:confirm={createTag}/>
|
||||
<TagEditor {isPremium} on:cancel={() => tagCreateModal = false} on:confirm={createTag}/>
|
||||
{:else if tagEditModal}
|
||||
<TagEditor {isPremium} bind:data={editData} on:cancel={cancelEdit} on:confirm={editTag}/>
|
||||
<TagEditor {isPremium} bind:data={editData} on:cancel={cancelEdit} on:confirm={editTag}/>
|
||||
{/if}
|
||||
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<div class="main-col">
|
||||
<Card footer footerRight>
|
||||
<div class="content">
|
||||
<Card footer footerRight>
|
||||
<span slot="title">Tags</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag</th>
|
||||
<th style="text-align: right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each Object.entries(tags) as [id, tag]}
|
||||
<tr>
|
||||
<td>{id}</td>
|
||||
<td class="actions">
|
||||
<Button type="button" on:click={() => openEditModal(id)}>Edit</Button>
|
||||
<Button type="button" danger={true} on:click={() => deleteTag(id)}>Delete</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag</th>
|
||||
<th style="text-align: right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each Object.entries(tags) as [id, tag]}
|
||||
<tr>
|
||||
<td>{id}</td>
|
||||
<td class="actions">
|
||||
<Button type="button" on:click={() => openEditModal(id)}>Edit</Button>
|
||||
<Button type="button" danger={true} on:click={() => deleteTag(id)}>Delete</Button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button icon="fas fa-plus" on:click={openCreateModal}>Create Tag</Button>
|
||||
<Button icon="fas fa-plus" on:click={openCreateModal}>Create Tag</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -45,7 +41,6 @@
|
||||
import axios from "axios";
|
||||
import {API_URL} from "../js/constants";
|
||||
import {setDefaultHeaders} from '../includes/Auth.svelte'
|
||||
import {fade} from "svelte/transition";
|
||||
import TagEditor from "../components/manage/TagEditor.svelte";
|
||||
|
||||
export let currentRoute;
|
||||
@ -61,7 +56,7 @@
|
||||
|
||||
function openCreateModal(id) {
|
||||
tagCreateModal = true;
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
window.scrollTo({top: 0, behavior: 'smooth'});
|
||||
}
|
||||
|
||||
function openEditModal(id) {
|
||||
@ -69,7 +64,7 @@
|
||||
editData = tags[id];
|
||||
tagEditModal = true;
|
||||
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
window.scrollTo({top: 0, behavior: 'smooth'});
|
||||
}
|
||||
|
||||
function cancelEdit() {
|
||||
@ -192,27 +187,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.main-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 64%;
|
||||
height: 100%;
|
||||
padding-bottom: 4%;
|
||||
}
|
||||
|
||||
.body-wrapper {
|
||||
|
@ -1,4 +1,3 @@
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<Card footer={false}>
|
||||
<span slot="title">Support Teams</span>
|
||||
@ -76,7 +75,6 @@
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import Card from "../components/Card.svelte";
|
||||
@ -226,19 +224,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.body-wrapper {
|
||||
|
@ -1,44 +1,42 @@
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<div class="content">
|
||||
<Card footer={false}>
|
||||
<span slot="title">Open Tickets</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Panel</th>
|
||||
<th>User</th>
|
||||
<th>View</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tickets as ticket}
|
||||
<tr>
|
||||
<td>{ticket.id}</td>
|
||||
<td>{ticket.panel_title}</td>
|
||||
{#if ticket.user !== undefined}
|
||||
<td>{ticket.user.username}</td>
|
||||
{:else}
|
||||
<td>Unknown</td>
|
||||
{/if}
|
||||
<td>
|
||||
<Navigate to="/manage/{guildId}/tickets/view/{ticket.id}" styles="link">
|
||||
<Button type="button">View</Button>
|
||||
</Navigate>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<span slot="title">Open Tickets</span>
|
||||
<div slot="body" class="body-wrapper">
|
||||
<table class="nice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Panel</th>
|
||||
<th>User</th>
|
||||
<th>View</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tickets as ticket}
|
||||
<tr>
|
||||
<td>{ticket.id}</td>
|
||||
<td>{ticket.panel_title}</td>
|
||||
{#if ticket.user !== undefined}
|
||||
<td>{ticket.user.username}</td>
|
||||
{:else}
|
||||
<td>Unknown</td>
|
||||
{/if}
|
||||
<td>
|
||||
<Navigate to="/manage/{guildId}/tickets/view/{ticket.id}" styles="link">
|
||||
<Button type="button">View</Button>
|
||||
</Navigate>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import Card from "../components/Card.svelte";
|
||||
import {notifyError, notifySuccess, withLoadingScreen} from '../js/util'
|
||||
import {notifyError, withLoadingScreen} from '../js/util'
|
||||
import axios from "axios";
|
||||
import {API_URL} from "../js/constants";
|
||||
import {setDefaultHeaders} from '../includes/Auth.svelte'
|
||||
@ -67,20 +65,10 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.body-wrapper {
|
||||
|
@ -242,9 +242,8 @@
|
||||
.col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 95%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.main-col {
|
||||
|
@ -1,65 +1,65 @@
|
||||
<div class="parent">
|
||||
<div class="content">
|
||||
<div class="content">
|
||||
<div class="container">
|
||||
<div class="spread">
|
||||
<h4 class="title">My Integrations</h4>
|
||||
<Button icon="fas fa-server" on:click={() => navigateTo(`/manage/${guildId}/integrations/create`)}>Create
|
||||
Integration
|
||||
</Button>
|
||||
</div>
|
||||
<div class="integrations my-integrations">
|
||||
{#each ownedIntegrations as integration}
|
||||
<div class="integration">
|
||||
<Integration owned name={integration.name} {guildId} integrationId={integration.id}
|
||||
imageUrl={generateProxyUrl(integration)} guildCount={integration.guild_count}>
|
||||
<div class="spread">
|
||||
<h4 class="title">My Integrations</h4>
|
||||
<Button icon="fas fa-server" on:click={() => navigateTo(`/manage/${guildId}/integrations/create`)}>Create
|
||||
Integration
|
||||
</Button>
|
||||
</div>
|
||||
<div class="integrations my-integrations">
|
||||
{#each ownedIntegrations as integration}
|
||||
<div class="integration">
|
||||
<Integration owned name={integration.name} {guildId} integrationId={integration.id}
|
||||
imageUrl={generateProxyUrl(integration)} guildCount={integration.guild_count}>
|
||||
<span slot="description">
|
||||
{integration.description}
|
||||
</span>
|
||||
</Integration>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Integration>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 class="title">Available Integrations</h4>
|
||||
<div class="integrations">
|
||||
<!-- Built in -->
|
||||
{#if page === 1}
|
||||
<div class="integration">
|
||||
<Integration builtIn name="Bloxlink"
|
||||
imageUrl="https://dbl-static.b-cdn.net/9bbd1f9504ddefc89606b19b290e9a0f.png"
|
||||
viewLink="https://docs.ticketsbot.net/dashboard/settings/placeholders#bloxlink">
|
||||
<h4 class="title">Available Integrations</h4>
|
||||
<div class="integrations">
|
||||
<!-- Built in -->
|
||||
{#if page === 1}
|
||||
<div class="integration">
|
||||
<Integration builtIn name="Bloxlink"
|
||||
imageUrl="https://dbl-static.b-cdn.net/9bbd1f9504ddefc89606b19b290e9a0f.png"
|
||||
viewLink="https://docs.ticketsbot.net/dashboard/settings/placeholders#bloxlink">
|
||||
<span slot="description">
|
||||
Our Bloxlink integration inserts the Roblox usernames, profile URLs and more of your users into
|
||||
ticket welcome messages automatically! This integration is automatically enabled in all servers, press the
|
||||
View button below to check out the full list of placeholders you can use!
|
||||
</span>
|
||||
</Integration>
|
||||
</div>
|
||||
{/if}
|
||||
</Integration>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#each availableIntegrations as integration}
|
||||
<div class="integration">
|
||||
<Integration name={integration.name} {guildId} integrationId={integration.id}
|
||||
imageUrl={generateProxyUrl(integration)} ownerId={integration.owner_id}
|
||||
added={integration.added} guildCount={integration.guild_count} showAuthor
|
||||
author={integration.author} on:remove={() => removeIntegration(integration.id)}>
|
||||
{#each availableIntegrations as integration}
|
||||
<div class="integration">
|
||||
<Integration name={integration.name} {guildId} integrationId={integration.id}
|
||||
imageUrl={generateProxyUrl(integration)} ownerId={integration.owner_id}
|
||||
added={integration.added} guildCount={integration.guild_count} showAuthor
|
||||
author={integration.author} on:remove={() => removeIntegration(integration.id)}>
|
||||
<span slot="description">
|
||||
{integration.description}
|
||||
</span>
|
||||
</Integration>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Integration>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page === 1} on:click={previousPage}></i>
|
||||
<p>Page {page}</p>
|
||||
<i class="fas fa-chevron-right pagination-chevron" class:disabled-chevron={!hasNextPage} on:click={nextPage}></i>
|
||||
<i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page === 1}
|
||||
on:click={previousPage}></i>
|
||||
<p>Page {page}</p>
|
||||
<i class="fas fa-chevron-right pagination-chevron" class:disabled-chevron={!hasNextPage}
|
||||
on:click={nextPage}></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@ -161,21 +161,12 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.parent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-top: 30px;
|
||||
padding-bottom: 5vh;
|
||||
row-gap: 4vh;
|
||||
}
|
||||
|
||||
@ -193,7 +184,7 @@
|
||||
}
|
||||
|
||||
.integration {
|
||||
flex: 0 0 23.5%;
|
||||
flex: 0 0 32%;
|
||||
}
|
||||
|
||||
.my-integrations {
|
||||
@ -231,19 +222,13 @@
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1180px) {
|
||||
.integration {
|
||||
flex: 0 0 32%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 930px) {
|
||||
@media only screen and (max-width: 1200px) {
|
||||
.integration {
|
||||
flex: 0 0 49%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 576px) {
|
||||
@media only screen and (max-width: 850px) {
|
||||
.integration {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin-top: 30px;
|
||||
gap: 2%;
|
||||
}
|
||||
|
||||
.col {
|
||||
@ -219,7 +219,7 @@
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
width: 96%;
|
||||
width: 100%;
|
||||
margin-bottom: 2%;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user