diff --git a/api_service/dashboard_web/css/components.css b/api_service/dashboard_web/css/components.css new file mode 100644 index 0000000..a29a79d --- /dev/null +++ b/api_service/dashboard_web/css/components.css @@ -0,0 +1,508 @@ +/* Components CSS file for the Discord Bot Dashboard */ + +/* Loading Spinner */ +.loading-spinner-container { + display: flex; + justify-content: center; + align-items: center; + padding: var(--spacing-6); +} + +.loading-spinner { + width: 40px; + height: 40px; + border: 4px solid rgba(88, 101, 242, 0.2); + border-radius: 50%; + border-top-color: var(--primary-color); + animation: spin 1s ease-in-out infinite; +} + +.loading-spinner-sm { + width: 20px; + height: 20px; + border-width: 2px; +} + +.loading-spinner-lg { + width: 60px; + height: 60px; + border-width: 6px; +} + +.loading-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.7); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +/* Button with loading state */ +.btn-loading { + position: relative; + pointer-events: none; + color: transparent !important; +} + +.btn-loading::after { + content: ""; + position: absolute; + width: 16px; + height: 16px; + top: calc(50% - 8px); + left: calc(50% - 8px); + border: 2px solid rgba(255, 255, 255, 0.5); + border-radius: 50%; + border-top-color: white; + animation: spin 1s ease-in-out infinite; +} + +/* Toast Notifications */ +.toast-container { + position: fixed; + bottom: 20px; + right: 20px; + z-index: 1000; + display: flex; + flex-direction: column; + gap: var(--spacing-2); +} + +.toast { + padding: var(--spacing-3) var(--spacing-4); + border-radius: var(--radius-md); + background-color: var(--card-bg); + box-shadow: var(--shadow-lg); + display: flex; + align-items: center; + gap: var(--spacing-3); + min-width: 300px; + max-width: 450px; + animation: slideIn 0.3s ease-out forwards; +} + +.toast.toast-success { + border-left: 4px solid var(--success-color); +} + +.toast.toast-error { + border-left: 4px solid var(--danger-color); +} + +.toast.toast-warning { + border-left: 4px solid var(--warning-color); +} + +.toast.toast-info { + border-left: 4px solid var(--primary-color); +} + +.toast-icon { + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.toast-content { + flex: 1; +} + +.toast-title { + font-weight: 600; + margin-bottom: var(--spacing-1); +} + +.toast-message { + color: var(--text-secondary); + font-size: 0.875rem; +} + +.toast-close { + background: none; + border: none; + cursor: pointer; + color: var(--text-secondary); + font-size: 1.25rem; + padding: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.toast-close:hover { + color: var(--text-primary); +} + +.toast.toast-hiding { + animation: slideOut 0.3s ease-in forwards; +} + +@keyframes slideIn { + from { + transform: translateX(100%); + opacity: 0; + } + to { + transform: translateX(0); + opacity: 1; + } +} + +@keyframes slideOut { + from { + transform: translateX(0); + opacity: 1; + } + to { + transform: translateX(100%); + opacity: 0; + } +} + +/* Badges */ +.badge { + display: inline-block; + padding: 0.25em 0.6em; + font-size: 0.75rem; + font-weight: 600; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 10px; +} + +.badge-primary { + background-color: var(--primary-color); + color: white; +} + +.badge-secondary { + background-color: var(--secondary-color); + color: white; +} + +.badge-success { + background-color: var(--success-color); + color: white; +} + +.badge-warning { + background-color: var(--warning-color); + color: white; +} + +.badge-danger { + background-color: var(--danger-color); + color: white; +} + +.badge-light { + background-color: #e2e8f0; + color: var(--text-primary); +} + +/* Tabs */ +.tabs { + display: flex; + border-bottom: 1px solid var(--border-color); + margin-bottom: var(--spacing-6); +} + +.tab { + padding: var(--spacing-3) var(--spacing-4); + cursor: pointer; + border-bottom: 2px solid transparent; + font-weight: 500; + color: var(--text-secondary); + transition: all 0.2s; +} + +.tab:hover { + color: var(--primary-color); +} + +.tab.active { + color: var(--primary-color); + border-bottom-color: var(--primary-color); +} + +.tab-content { + display: none; +} + +.tab-content.active { + display: block; +} + +/* Modals */ +.modal { + display: none; + position: fixed; + z-index: 1000; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + animation: fadeIn 0.3s; +} + +.modal.active { + display: flex; + align-items: center; + justify-content: center; +} + +.modal-content { + background-color: var(--card-bg); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); + width: 90%; + max-width: 500px; + animation: scaleIn 0.3s; + position: relative; + max-height: 90vh; + display: flex; + flex-direction: column; +} + +.modal-header { + padding: var(--spacing-4) var(--spacing-6); + border-bottom: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; +} + +.modal-title { + font-size: 1.25rem; + font-weight: 600; + margin: 0; +} + +.modal-close { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: var(--text-secondary); + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 50%; +} + +.modal-close:hover { + background-color: rgba(0, 0, 0, 0.05); + color: var(--text-primary); +} + +.modal-body { + padding: var(--spacing-6); + overflow-y: auto; +} + +.modal-footer { + padding: var(--spacing-4) var(--spacing-6); + border-top: 1px solid var(--border-color); + display: flex; + justify-content: flex-end; + gap: var(--spacing-3); +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes scaleIn { + from { + transform: scale(0.9); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} + +/* Dropdowns */ +.dropdown { + position: relative; + display: inline-block; +} + +.dropdown-toggle { + cursor: pointer; + display: flex; + align-items: center; + gap: var(--spacing-2); +} + +.dropdown-menu { + position: absolute; + top: 100%; + right: 0; + z-index: 1000; + display: none; + min-width: 180px; + padding: var(--spacing-2) 0; + margin: var(--spacing-1) 0 0; + background-color: var(--card-bg); + border-radius: var(--radius-md); + box-shadow: var(--shadow-lg); +} + +.dropdown-menu.show { + display: block; + animation: fadeIn 0.2s; +} + +.dropdown-item { + display: block; + width: 100%; + padding: var(--spacing-2) var(--spacing-4); + clear: both; + font-weight: 400; + color: var(--text-primary); + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; + text-decoration: none; + cursor: pointer; +} + +.dropdown-item:hover { + background-color: rgba(0, 0, 0, 0.05); + text-decoration: none; +} + +.dropdown-divider { + height: 0; + margin: var(--spacing-2) 0; + overflow: hidden; + border-top: 1px solid var(--border-color); +} + +/* Alerts */ +.alert { + position: relative; + padding: var(--spacing-4); + margin-bottom: var(--spacing-4); + border: 1px solid transparent; + border-radius: var(--radius-md); +} + +.alert-success { + color: #0f5132; + background-color: #d1e7dd; + border-color: #badbcc; +} + +.alert-danger { + color: #842029; + background-color: #f8d7da; + border-color: #f5c2c7; +} + +.alert-warning { + color: #664d03; + background-color: #fff3cd; + border-color: #ffecb5; +} + +.alert-info { + color: #055160; + background-color: #cff4fc; + border-color: #b6effb; +} + +.alert-dismissible { + padding-right: 3rem; +} + +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: var(--spacing-4); + color: inherit; + background: transparent; + border: 0; + cursor: pointer; +} + +/* Progress Bar */ +.progress { + display: flex; + height: 0.75rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: var(--radius-md); +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: var(--primary-color); + transition: width 0.6s ease; +} + +/* Tooltips */ +.tooltip { + position: relative; + display: inline-block; +} + +.tooltip .tooltip-text { + visibility: hidden; + width: 120px; + background-color: var(--secondary-color); + color: #fff; + text-align: center; + border-radius: var(--radius-sm); + padding: var(--spacing-2); + position: absolute; + z-index: 1; + bottom: 125%; + left: 50%; + margin-left: -60px; + opacity: 0; + transition: opacity 0.3s; + font-size: 0.75rem; +} + +.tooltip .tooltip-text::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: var(--secondary-color) transparent transparent transparent; +} + +.tooltip:hover .tooltip-text { + visibility: visible; + opacity: 1; +} diff --git a/api_service/dashboard_web/css/layout.css b/api_service/dashboard_web/css/layout.css new file mode 100644 index 0000000..6f5ff83 --- /dev/null +++ b/api_service/dashboard_web/css/layout.css @@ -0,0 +1,290 @@ +/* Layout CSS file for the Discord Bot Dashboard */ + +/* Grid System */ +.row { + display: flex; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.col { + position: relative; + width: 100%; + padding-right: 15px; + padding-left: 15px; +} + +.col-1 { flex: 0 0 8.333333%; max-width: 8.333333%; } +.col-2 { flex: 0 0 16.666667%; max-width: 16.666667%; } +.col-3 { flex: 0 0 25%; max-width: 25%; } +.col-4 { flex: 0 0 33.333333%; max-width: 33.333333%; } +.col-5 { flex: 0 0 41.666667%; max-width: 41.666667%; } +.col-6 { flex: 0 0 50%; max-width: 50%; } +.col-7 { flex: 0 0 58.333333%; max-width: 58.333333%; } +.col-8 { flex: 0 0 66.666667%; max-width: 66.666667%; } +.col-9 { flex: 0 0 75%; max-width: 75%; } +.col-10 { flex: 0 0 83.333333%; max-width: 83.333333%; } +.col-11 { flex: 0 0 91.666667%; max-width: 91.666667%; } +.col-12 { flex: 0 0 100%; max-width: 100%; } + +/* Responsive Breakpoints */ +@media (max-width: 576px) { + .col-sm-1 { flex: 0 0 8.333333%; max-width: 8.333333%; } + .col-sm-2 { flex: 0 0 16.666667%; max-width: 16.666667%; } + .col-sm-3 { flex: 0 0 25%; max-width: 25%; } + .col-sm-4 { flex: 0 0 33.333333%; max-width: 33.333333%; } + .col-sm-5 { flex: 0 0 41.666667%; max-width: 41.666667%; } + .col-sm-6 { flex: 0 0 50%; max-width: 50%; } + .col-sm-7 { flex: 0 0 58.333333%; max-width: 58.333333%; } + .col-sm-8 { flex: 0 0 66.666667%; max-width: 66.666667%; } + .col-sm-9 { flex: 0 0 75%; max-width: 75%; } + .col-sm-10 { flex: 0 0 83.333333%; max-width: 83.333333%; } + .col-sm-11 { flex: 0 0 91.666667%; max-width: 91.666667%; } + .col-sm-12 { flex: 0 0 100%; max-width: 100%; } +} + +@media (max-width: 768px) { + .col-md-1 { flex: 0 0 8.333333%; max-width: 8.333333%; } + .col-md-2 { flex: 0 0 16.666667%; max-width: 16.666667%; } + .col-md-3 { flex: 0 0 25%; max-width: 25%; } + .col-md-4 { flex: 0 0 33.333333%; max-width: 33.333333%; } + .col-md-5 { flex: 0 0 41.666667%; max-width: 41.666667%; } + .col-md-6 { flex: 0 0 50%; max-width: 50%; } + .col-md-7 { flex: 0 0 58.333333%; max-width: 58.333333%; } + .col-md-8 { flex: 0 0 66.666667%; max-width: 66.666667%; } + .col-md-9 { flex: 0 0 75%; max-width: 75%; } + .col-md-10 { flex: 0 0 83.333333%; max-width: 83.333333%; } + .col-md-11 { flex: 0 0 91.666667%; max-width: 91.666667%; } + .col-md-12 { flex: 0 0 100%; max-width: 100%; } + + /* Mobile sidebar adjustments */ + .sidebar { + transform: translateX(-100%); + transition: transform 0.3s ease; + } + + .sidebar.show { + transform: translateX(0); + } + + .main-content { + margin-left: 0; + transition: margin-left 0.3s ease; + } + + .header { + left: 0; + transition: left 0.3s ease; + } + + .sidebar-toggle { + display: block !important; + } +} + +@media (max-width: 992px) { + .col-lg-1 { flex: 0 0 8.333333%; max-width: 8.333333%; } + .col-lg-2 { flex: 0 0 16.666667%; max-width: 16.666667%; } + .col-lg-3 { flex: 0 0 25%; max-width: 25%; } + .col-lg-4 { flex: 0 0 33.333333%; max-width: 33.333333%; } + .col-lg-5 { flex: 0 0 41.666667%; max-width: 41.666667%; } + .col-lg-6 { flex: 0 0 50%; max-width: 50%; } + .col-lg-7 { flex: 0 0 58.333333%; max-width: 58.333333%; } + .col-lg-8 { flex: 0 0 66.666667%; max-width: 66.666667%; } + .col-lg-9 { flex: 0 0 75%; max-width: 75%; } + .col-lg-10 { flex: 0 0 83.333333%; max-width: 83.333333%; } + .col-lg-11 { flex: 0 0 91.666667%; max-width: 91.666667%; } + .col-lg-12 { flex: 0 0 100%; max-width: 100%; } +} + +@media (max-width: 1200px) { + .col-xl-1 { flex: 0 0 8.333333%; max-width: 8.333333%; } + .col-xl-2 { flex: 0 0 16.666667%; max-width: 16.666667%; } + .col-xl-3 { flex: 0 0 25%; max-width: 25%; } + .col-xl-4 { flex: 0 0 33.333333%; max-width: 33.333333%; } + .col-xl-5 { flex: 0 0 41.666667%; max-width: 41.666667%; } + .col-xl-6 { flex: 0 0 50%; max-width: 50%; } + .col-xl-7 { flex: 0 0 58.333333%; max-width: 58.333333%; } + .col-xl-8 { flex: 0 0 66.666667%; max-width: 66.666667%; } + .col-xl-9 { flex: 0 0 75%; max-width: 75%; } + .col-xl-10 { flex: 0 0 83.333333%; max-width: 83.333333%; } + .col-xl-11 { flex: 0 0 91.666667%; max-width: 91.666667%; } + .col-xl-12 { flex: 0 0 100%; max-width: 100%; } +} + +/* Sidebar Toggle Button (hidden by default, shown on mobile) */ +.sidebar-toggle { + display: none; + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + color: var(--text-primary); + padding: 0; + margin-right: var(--spacing-4); +} + +/* Responsive Containers */ +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +/* Flexbox Utilities */ +.d-flex { + display: flex !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +/* Spacing Utilities */ +.m-0 { margin: 0 !important; } +.mt-0 { margin-top: 0 !important; } +.mr-0 { margin-right: 0 !important; } +.mb-0 { margin-bottom: 0 !important; } +.ml-0 { margin-left: 0 !important; } + +.p-0 { padding: 0 !important; } +.pt-0 { padding-top: 0 !important; } +.pr-0 { padding-right: 0 !important; } +.pb-0 { padding-bottom: 0 !important; } +.pl-0 { padding-left: 0 !important; } + +/* Display Utilities */ +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +@media (min-width: 576px) { + .d-sm-none { display: none !important; } + .d-sm-inline { display: inline !important; } + .d-sm-inline-block { display: inline-block !important; } + .d-sm-block { display: block !important; } + .d-sm-flex { display: flex !important; } +} + +@media (min-width: 768px) { + .d-md-none { display: none !important; } + .d-md-inline { display: inline !important; } + .d-md-inline-block { display: inline-block !important; } + .d-md-block { display: block !important; } + .d-md-flex { display: flex !important; } +} + +@media (min-width: 992px) { + .d-lg-none { display: none !important; } + .d-lg-inline { display: inline !important; } + .d-lg-inline-block { display: inline-block !important; } + .d-lg-block { display: block !important; } + .d-lg-flex { display: flex !important; } +} + +@media (min-width: 1200px) { + .d-xl-none { display: none !important; } + .d-xl-inline { display: inline !important; } + .d-xl-inline-block { display: inline-block !important; } + .d-xl-block { display: block !important; } + .d-xl-flex { display: flex !important; } +} diff --git a/api_service/dashboard_web/css/main.css b/api_service/dashboard_web/css/main.css new file mode 100644 index 0000000..738e613 --- /dev/null +++ b/api_service/dashboard_web/css/main.css @@ -0,0 +1,470 @@ +/* Main CSS file for the Discord Bot Dashboard */ + +:root { + /* Color variables */ + --primary-color: #5865F2; /* Discord blue */ + --primary-hover: #4752C4; + --secondary-color: #2D3748; + --accent-color: #7289DA; + --success-color: #48BB78; + --warning-color: #F6AD55; + --danger-color: #F56565; + --light-bg: #F7FAFC; + --dark-bg: #1A202C; + --card-bg: #FFFFFF; + --text-primary: #2D3748; + --text-secondary: #718096; + --border-color: #E2E8F0; + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + --radius-sm: 0.25rem; + --radius-md: 0.375rem; + --radius-lg: 0.5rem; + + /* Spacing variables */ + --spacing-1: 0.25rem; + --spacing-2: 0.5rem; + --spacing-3: 0.75rem; + --spacing-4: 1rem; + --spacing-6: 1.5rem; + --spacing-8: 2rem; + --spacing-12: 3rem; + --spacing-16: 4rem; +} + +/* Base styles */ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + font-size: 16px; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + background-color: var(--light-bg); + color: var(--text-primary); + line-height: 1.5; + min-height: 100vh; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 600; + line-height: 1.25; + margin-bottom: var(--spacing-4); + color: var(--secondary-color); +} + +h1 { + font-size: 2rem; +} + +h2 { + font-size: 1.5rem; +} + +h3 { + font-size: 1.25rem; +} + +h4 { + font-size: 1rem; +} + +a { + color: var(--primary-color); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +/* Layout */ +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 var(--spacing-4); +} + +.dashboard-container { + display: flex; + min-height: 100vh; +} + +.main-content { + flex: 1; + padding: var(--spacing-6); + margin-left: 250px; /* Width of the sidebar */ +} + +/* Header */ +.header { + background-color: var(--card-bg); + border-bottom: 1px solid var(--border-color); + padding: var(--spacing-4) var(--spacing-6); + display: flex; + justify-content: space-between; + align-items: center; + position: fixed; + top: 0; + right: 0; + left: 250px; /* Width of the sidebar */ + height: 64px; + z-index: 10; + box-shadow: var(--shadow-sm); +} + +.header-title { + font-size: 1.25rem; + margin: 0; +} + +.user-info { + display: flex; + align-items: center; + gap: var(--spacing-3); +} + +.user-avatar { + width: 36px; + height: 36px; + border-radius: 50%; + background-color: var(--primary-color); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 600; +} + +.user-name { + font-weight: 500; +} + +/* Sidebar */ +.sidebar { + width: 250px; + background-color: var(--secondary-color); + color: white; + position: fixed; + top: 0; + left: 0; + bottom: 0; + overflow-y: auto; + z-index: 20; +} + +.sidebar-header { + padding: var(--spacing-6); + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.sidebar-logo { + font-size: 1.5rem; + font-weight: 700; + color: white; + text-decoration: none; +} + +.sidebar-nav { + padding: var(--spacing-4) 0; +} + +.nav-item { + padding: var(--spacing-3) var(--spacing-6); + display: flex; + align-items: center; + gap: var(--spacing-3); + color: rgba(255, 255, 255, 0.8); + text-decoration: none; + transition: background-color 0.2s; +} + +.nav-item:hover { + background-color: rgba(255, 255, 255, 0.1); + color: white; + text-decoration: none; +} + +.nav-item.active { + background-color: var(--primary-color); + color: white; +} + +.nav-icon { + width: 20px; + height: 20px; +} + +.sidebar-footer { + padding: var(--spacing-4) var(--spacing-6); + border-top: 1px solid rgba(255, 255, 255, 0.1); + position: absolute; + bottom: 0; + width: 100%; +} + +/* Cards */ +.card { + background-color: var(--card-bg); + border-radius: var(--radius-md); + box-shadow: var(--shadow-md); + padding: var(--spacing-6); + margin-bottom: var(--spacing-6); +} + +.card-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-4); +} + +.card-title { + font-size: 1.25rem; + margin: 0; +} + +/* Forms */ +.form-group { + margin-bottom: var(--spacing-4); +} + +label { + display: block; + margin-bottom: var(--spacing-2); + font-weight: 500; +} + +input[type="text"], +input[type="number"], +input[type="password"], +input[type="email"], +input[type="search"], +select, +textarea { + width: 100%; + padding: var(--spacing-3); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + background-color: white; + font-size: 1rem; + transition: border-color 0.2s; +} + +input:focus, +select:focus, +textarea:focus { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 0 3px rgba(88, 101, 242, 0.2); +} + +textarea { + resize: vertical; + min-height: 100px; +} + +input[type="checkbox"], +input[type="radio"] { + margin-right: var(--spacing-2); +} + +.checkbox-label, +.radio-label { + display: flex; + align-items: center; + cursor: pointer; +} + +/* Buttons */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: var(--spacing-2) var(--spacing-4); + border: none; + border-radius: var(--radius-md); + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: background-color 0.2s, transform 0.1s; +} + +.btn:hover { + transform: translateY(-1px); +} + +.btn:active { + transform: translateY(0); +} + +.btn-primary { + background-color: var(--primary-color); + color: white; +} + +.btn-primary:hover { + background-color: var(--primary-hover); +} + +.btn-secondary { + background-color: var(--secondary-color); + color: white; +} + +.btn-secondary:hover { + background-color: #3a4a63; +} + +.btn-success { + background-color: var(--success-color); + color: white; +} + +.btn-success:hover { + background-color: #3da066; +} + +.btn-warning { + background-color: var(--warning-color); + color: white; +} + +.btn-warning:hover { + background-color: #e09c49; +} + +.btn-danger { + background-color: var(--danger-color); + color: white; +} + +.btn-danger:hover { + background-color: #e04c4c; +} + +.btn-sm { + font-size: 0.875rem; + padding: var(--spacing-1) var(--spacing-3); +} + +.btn-lg { + font-size: 1.125rem; + padding: var(--spacing-3) var(--spacing-6); +} + +.btn-icon { + display: inline-flex; + align-items: center; + gap: var(--spacing-2); +} + +.btn-group { + display: flex; + gap: var(--spacing-3); +} + +/* Utilities */ +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.mt-1 { margin-top: var(--spacing-1); } +.mt-2 { margin-top: var(--spacing-2); } +.mt-4 { margin-top: var(--spacing-4); } +.mt-6 { margin-top: var(--spacing-6); } + +.mb-1 { margin-bottom: var(--spacing-1); } +.mb-2 { margin-bottom: var(--spacing-2); } +.mb-4 { margin-bottom: var(--spacing-4); } +.mb-6 { margin-bottom: var(--spacing-6); } + +.ml-1 { margin-left: var(--spacing-1); } +.ml-2 { margin-left: var(--spacing-2); } +.ml-4 { margin-left: var(--spacing-4); } +.ml-6 { margin-left: var(--spacing-6); } + +.mr-1 { margin-right: var(--spacing-1); } +.mr-2 { margin-right: var(--spacing-2); } +.mr-4 { margin-right: var(--spacing-4); } +.mr-6 { margin-right: var(--spacing-6); } + +.p-1 { padding: var(--spacing-1); } +.p-2 { padding: var(--spacing-2); } +.p-4 { padding: var(--spacing-4); } +.p-6 { padding: var(--spacing-6); } + +.hidden { + display: none !important; +} + +.flex { + display: flex; +} + +.flex-col { + flex-direction: column; +} + +.items-center { + align-items: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-center { + justify-content: center; +} + +.gap-2 { + gap: var(--spacing-2); +} + +.gap-4 { + gap: var(--spacing-4); +} + +.w-full { + width: 100%; +} + +.text-sm { + font-size: 0.875rem; +} + +.text-lg { + font-size: 1.125rem; +} + +.font-bold { + font-weight: 700; +} + +.text-gray { + color: var(--text-secondary); +} + +.text-success { + color: var(--success-color); +} + +.text-warning { + color: var(--warning-color); +} + +.text-danger { + color: var(--danger-color); +} diff --git a/api_service/dashboard_web/index.html b/api_service/dashboard_web/index.html index 488d255..7b7241e 100644 --- a/api_service/dashboard_web/index.html +++ b/api_service/dashboard_web/index.html @@ -4,49 +4,114 @@
Manage your Discord bot settings and configurations
+ +