Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 59 additions & 8 deletions frontend/src/components/Guild.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<script>
import Tooltip from "svelte-tooltip";
import { DOCS_URL } from "../js/constants";
import NoPermissionModal from "./NoPermissionModal.svelte";

export let guild;

let showNoPermissionModal = false;

function isAnimated() {
if (guild.icon === undefined || guild.icon === "") {
return false;
Expand All @@ -29,6 +32,15 @@
return;
}
}

function openNoPermissionModal(event) {
event.stopPropagation();
showNoPermissionModal = true;
}

function closeNoPermissionModal() {
showNoPermissionModal = false;
}
</script>

<div
Expand Down Expand Up @@ -60,24 +72,30 @@
<span class="no-permission">
No permission
<Tooltip
tip="You do not have permission to manage this server."
tip="Click to learn how to get access"
top
color="#121212"
>
<a
href={`${DOCS_URL}/miscellaneous/dashboard-no-permission`}
target="_blank"
<button
class="info-button"
on:click={openNoPermissionModal}
aria-label="Learn how to get access"
>
<i
class="fas fa-circle-question form-label tooltip-icon"
></i>
</a>
<i class="fas fa-circle-question"></i>
</button>
</Tooltip>
</span>
{/if}
</div>
</div>

{#if showNoPermissionModal}
<NoPermissionModal
isOwner={guild.owner === true}
on:close={closeNoPermissionModal}
/>
{/if}

<style>
:global(.guild-badge) {
display: flex;
Expand Down Expand Up @@ -146,5 +164,38 @@

.text-wrapper > .no-permission {
opacity: 75%;
display: flex;
align-items: center;
gap: 6px;
}

.info-button {
background: none;
border: none;
color: #5865f2;
cursor: pointer;
padding: 0;
margin: 0;
font-size: 14px;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
filter: drop-shadow(0 0 0px rgba(88, 101, 242, 0));
}

.info-button:hover {
color: #7289da;
transform: scale(1.2) rotate(15deg);
filter: drop-shadow(0 0 6px rgba(88, 101, 242, 0.6));
}

.info-button:active {
transform: scale(1.1) rotate(10deg);
}

.info-button:focus {
outline: 2px solid #5865f2;
outline-offset: 2px;
border-radius: 2px;
}
</style>
273 changes: 273 additions & 0 deletions frontend/src/components/NoPermissionModal.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
<script>
import { fade } from 'svelte/transition';
import Card from './Card.svelte';
import Button from './Button.svelte';
import { createEventDispatcher } from 'svelte';

const dispatch = createEventDispatcher();

function closeModal() {
dispatch('close');
}

let wrapper;

// Close modal when clicking outside
function handleOutsideClick(event) {
// Only close if clicking directly on the modal backdrop
if (event.target.classList.contains('modal')) {
closeModal();
}
}
</script>

<svelte:window on:click={handleOutsideClick} />

<div class="modal" transition:fade={{ duration: 300 }}>
<div class="modal-wrapper" bind:this={wrapper}>
<Card footer={true} footerRight={true} fill={false}>
<span slot="title">Dashboard Access Required</span>

<div slot="body" class="body-wrapper">
<p class="intro">
For your server to appear on the dashboard, you need to be a designated <strong>Support Representative</strong> or <strong>Admin User</strong> for the @Tickets v2 bot in that server.
</p>

<div class="info-section">
<h3><i class="fas fa-check-circle"></i> How to Check Your Role</h3>
<p>
Run <code>/viewstaff</code> in your server to see who has access.
</p>
</div>

<div class="info-section">
<h3><i class="fas fa-user-shield"></i> Permission Levels</h3>
<ul>
<li>
<strong>Support Representatives:</strong> Limited dashboard access to tickets they can see and the tags page.
</li>
<li>
<strong>Admin Users:</strong> Full access to the entire bot dashboard, including adding/changing/removing settings and panels.
</li>
</ul>
<p class="learn-more">
<a href="https://docs.tickets.bot/setup/staff" target="_blank" rel="noopener noreferrer">
Learn more about Support and Admin roles <i class="fas fa-external-link-alt"></i>
</a>
</p>
</div>

<div class="info-section important">
<h3><i class="fas fa-exclamation-triangle"></i> Important Notes</h3>
<ul>
<li>
The Tickets dashboard <strong>does not check for server permissions</strong>. Discord's Administrator permission no longer provides access.
</li>
<li>
Ask your server owner or an existing Admin User to run <code>/addadmin @yourUsername</code> in your server.
</li>
<li>
After being added as an Admin User or Support Representative, you may need to <a href="/logout" class="logout-link">re-login</a> to the dashboard for the changes to take effect.
</li>
</ul>
</div>
</div>

<div slot="footer">
<Button on:click={closeModal}>
Got it
</Button>
</div>
</Card>
</div>
</div>

<div class="modal-backdrop" transition:fade={{ duration: 300 }}></div>

<style>
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1001;
display: flex;
justify-content: center;
align-items: center;
}

.modal-wrapper {
display: flex;
width: 60%;
max-width: 800px;
max-height: 90vh;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
margin: 20px;
}

.modal-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
background-color: #000;
opacity: 0.5;
}

.body-wrapper {
display: flex;
flex-direction: column;
gap: 20px;
color: #e0e0e0;
line-height: 1.6;
word-wrap: break-word;
overflow-wrap: break-word;
}

.intro {
font-size: 15px;
margin: 0;
}

.info-section {
padding: 16px;
background: rgba(26, 31, 46, 0.5);
border-radius: 8px;
border-left: 3px solid #5865f2;
overflow-wrap: break-word;
}

.info-section.important {
border-left-color: #faa61a;
background: rgba(250, 166, 26, 0.05);
}

.info-section h3 {
margin: 0 0 12px 0;
font-size: 16px;
color: #ffffff;
display: flex;
align-items: center;
gap: 8px;
}

.info-section h3 i {
color: #5865f2;
}

.info-section.important h3 i {
color: #faa61a;
}

.info-section p {
margin: 8px 0;
}

.info-section ul {
margin: 8px 0;
padding-left: 20px;
}

.info-section li {
margin: 8px 0;
}

code {
background: rgba(0, 0, 0, 0.3);
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
color: #faa61a;
font-size: 14px;
word-break: break-all;
overflow-wrap: anywhere;
}

.learn-more {
margin-top: 12px;
font-size: 14px;
}

.learn-more a {
color: #5865f2;
text-decoration: none;
transition: color 0.2s;
}

.learn-more a:hover {
color: #7289da;
text-decoration: underline;
}

.learn-more i {
font-size: 12px;
}

.logout-link {
color: #5865f2;
text-decoration: none;
font-weight: bold;
transition: color 0.2s;
}

.logout-link:hover {
color: #7289da;
text-decoration: underline;
}

strong {
color: #ffffff;
}

@media only screen and (max-width: 1280px) {
.modal-wrapper {
width: 90%;
}
}

@media only screen and (max-width: 768px) {
.modal {
align-items: flex-start;
overflow-y: auto;
}

.modal-wrapper {
width: 100%;
max-height: none;
}

.body-wrapper {
gap: 16px;
}

.info-section {
padding: 12px;
}

.info-section h3 {
font-size: 15px;
flex-wrap: wrap;
}

.info-section ul {
padding-left: 16px;
}

.info-section li {
margin: 6px 0;
}

.intro {
font-size: 14px;
}

code {
font-size: 12px;
padding: 2px 4px;
}
}
</style>
Loading