admin.css 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /* Admin Panel Specific Styles */
  2. /* Extend the container for admin panel to accommodate wider content */
  3. .admin-container {
  4. background: var(--container-bg);
  5. border-radius: 15px;
  6. box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
  7. overflow: hidden;
  8. width: 100%;
  9. max-width: 1200px;
  10. margin: 20px;
  11. transition: background 0.3s ease;
  12. min-height: 600px;
  13. }
  14. /* Header controls */
  15. .header-controls {
  16. position: absolute;
  17. top: 20px;
  18. right: 20px;
  19. display: flex;
  20. gap: 8px;
  21. align-items: center;
  22. }
  23. .header-btn {
  24. background: rgba(255, 255, 255, 0.2);
  25. border: 1px solid rgba(255, 255, 255, 0.3);
  26. border-radius: 50%;
  27. width: 40px;
  28. height: 40px;
  29. display: flex;
  30. align-items: center;
  31. justify-content: center;
  32. cursor: pointer;
  33. transition: all 0.3s ease;
  34. backdrop-filter: blur(10px);
  35. color: var(--header-text);
  36. }
  37. .header-btn:hover {
  38. background: rgba(255, 255, 255, 0.3);
  39. transform: scale(1.1);
  40. }
  41. .header-btn svg {
  42. transition: all 0.3s ease;
  43. }
  44. /* Admin controls section */
  45. .admin-controls {
  46. padding: 20px;
  47. background: var(--section-bg);
  48. border-bottom: 1px solid var(--border-color);
  49. transition: all 0.3s ease;
  50. }
  51. /* Stats cards */
  52. .stats-container {
  53. display: grid;
  54. grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  55. gap: 15px;
  56. margin-bottom: 20px;
  57. }
  58. .stat-card {
  59. background: var(--user-details-bg);
  60. padding: 20px;
  61. border-radius: 10px;
  62. text-align: center;
  63. border: 2px solid transparent;
  64. transition: all 0.3s ease;
  65. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  66. }
  67. .stat-card:hover {
  68. border-color: var(--tab-border);
  69. transform: translateY(-2px);
  70. }
  71. .stat-card h3 {
  72. font-size: 2rem;
  73. font-weight: bold;
  74. color: var(--tab-active-text);
  75. margin: 0 0 5px 0;
  76. transition: color 0.3s ease;
  77. }
  78. .stat-card p {
  79. font-size: 0.9rem;
  80. color: var(--text-secondary);
  81. margin: 0;
  82. transition: color 0.3s ease;
  83. }
  84. /* Control buttons */
  85. .control-buttons {
  86. display: flex;
  87. gap: 10px;
  88. flex-wrap: wrap;
  89. }
  90. .action-btn.secondary {
  91. background: var(--user-info-bg);
  92. color: var(--text-primary);
  93. border: 2px solid var(--border-color);
  94. }
  95. .action-btn.secondary:hover {
  96. background: var(--tab-active-bg);
  97. border-color: var(--tab-border);
  98. }
  99. .action-btn svg {
  100. margin-right: 5px;
  101. vertical-align: middle;
  102. }
  103. /* Users section */
  104. .users-section {
  105. padding: 20px;
  106. }
  107. .section-header {
  108. display: flex;
  109. justify-content: space-between;
  110. align-items: center;
  111. margin-bottom: 20px;
  112. flex-wrap: wrap;
  113. gap: 15px;
  114. }
  115. .section-header h2 {
  116. color: var(--text-primary);
  117. margin: 0;
  118. font-size: 1.5rem;
  119. transition: color 0.3s ease;
  120. }
  121. /* Search container */
  122. .search-container {
  123. position: relative;
  124. min-width: 250px;
  125. }
  126. .search-container input {
  127. width: 100%;
  128. padding: 10px 40px 10px 15px;
  129. border: 2px solid var(--input-border);
  130. border-radius: 25px;
  131. background: var(--input-bg);
  132. color: var(--input-text);
  133. font-size: 0.9rem;
  134. transition: all 0.3s ease;
  135. }
  136. .search-container input:focus {
  137. outline: none;
  138. border-color: var(--input-focus-border);
  139. box-shadow: 0 0 0 3px var(--input-focus-shadow);
  140. }
  141. .search-icon {
  142. position: absolute;
  143. right: 12px;
  144. top: 50%;
  145. transform: translateY(-50%);
  146. color: var(--text-secondary);
  147. pointer-events: none;
  148. transition: color 0.3s ease;
  149. }
  150. /* Table styles */
  151. .table-container {
  152. background: var(--user-details-bg);
  153. border-radius: 10px;
  154. overflow: hidden;
  155. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  156. transition: background 0.3s ease;
  157. }
  158. .users-table {
  159. width: 100%;
  160. border-collapse: collapse;
  161. font-size: 0.9rem;
  162. }
  163. .users-table th,
  164. .users-table td {
  165. padding: 15px 12px;
  166. text-align: left;
  167. border-bottom: 1px solid var(--border-color);
  168. transition: border-color 0.3s ease;
  169. }
  170. .users-table th {
  171. background: var(--section-bg);
  172. font-weight: 600;
  173. color: var(--text-primary);
  174. text-transform: uppercase;
  175. font-size: 0.8rem;
  176. letter-spacing: 0.5px;
  177. transition: all 0.3s ease;
  178. }
  179. .users-table tbody tr:hover {
  180. background: var(--section-bg);
  181. transition: background 0.3s ease;
  182. }
  183. .users-table tbody tr:last-child td {
  184. border-bottom: none;
  185. }
  186. /* Table cell content */
  187. .users-table .user-info {
  188. display: block !important;
  189. padding: 0;
  190. background: none;
  191. border: none;
  192. }
  193. .username {
  194. font-weight: 600;
  195. color: var(--text-primary);
  196. transition: color 0.3s ease;
  197. display: inline !important;
  198. }
  199. .email {
  200. color: var(--text-secondary);
  201. font-size: 0.85rem;
  202. transition: color 0.3s ease;
  203. }
  204. /* Role badges */
  205. .roles {
  206. display: flex;
  207. gap: 5px;
  208. flex-wrap: wrap;
  209. }
  210. .role-badge {
  211. display: inline-block;
  212. padding: 3px 8px;
  213. border-radius: 12px;
  214. font-size: 0.7rem;
  215. font-weight: 600;
  216. text-transform: uppercase;
  217. letter-spacing: 0.5px;
  218. transition: all 0.3s ease;
  219. }
  220. .role-badge.admin {
  221. background: linear-gradient(135deg, #ff6b6b, #ee5a52);
  222. color: white;
  223. }
  224. .role-badge.user {
  225. background: var(--section-bg);
  226. color: var(--text-secondary);
  227. border: 1px solid var(--border-color);
  228. }
  229. .role-badge.moderator {
  230. background: linear-gradient(135deg, #4ecdc4, #44a08d);
  231. color: white;
  232. }
  233. .role-badge.service {
  234. background: linear-gradient(135deg, #667eea, #764ba2);
  235. color: white;
  236. }
  237. .role-badge.system {
  238. background: linear-gradient(135deg, #2d3748, #4a5568);
  239. color: white;
  240. }
  241. .role-badge.vpn {
  242. background: linear-gradient(135deg, #48bb78, #38a169);
  243. color: white;
  244. }
  245. .role-badge.tester {
  246. background: linear-gradient(135deg, #ed8936, #dd6b20);
  247. color: white;
  248. }
  249. /* Default/fallback style for any unknown roles */
  250. .role-badge:not(.admin):not(.user):not(.moderator):not(.service):not(.system):not(.vpn):not(.tester) {
  251. background: linear-gradient(135deg, #718096, #4a5568);
  252. color: white;
  253. border: 1px solid var(--border-color);
  254. }
  255. /* Status badges */
  256. .status-badge {
  257. display: inline-block;
  258. padding: 4px 10px;
  259. border-radius: 15px;
  260. font-size: 0.75rem;
  261. font-weight: 600;
  262. text-transform: uppercase;
  263. letter-spacing: 0.5px;
  264. transition: all 0.3s ease;
  265. }
  266. .status-badge.active {
  267. background: var(--message-success-bg);
  268. color: var(--message-success-text);
  269. border: 1px solid var(--message-success-border);
  270. }
  271. .status-badge.inactive {
  272. background: var(--message-error-bg);
  273. color: var(--message-error-text);
  274. border: 1px solid var(--message-error-border);
  275. }
  276. /* Last login */
  277. .last-login {
  278. color: var(--text-secondary);
  279. font-size: 0.8rem;
  280. transition: color 0.3s ease;
  281. }
  282. /* Action buttons in table */
  283. .action-buttons {
  284. display: flex;
  285. gap: 5px;
  286. }
  287. .action-btn.small {
  288. padding: 6px 8px;
  289. font-size: 0.8rem;
  290. min-width: auto;
  291. width: auto;
  292. display: inline-flex;
  293. align-items: center;
  294. justify-content: center;
  295. }
  296. .action-btn.small svg {
  297. margin: 0;
  298. }
  299. /* Loading states */
  300. .loading-container {
  301. text-align: center;
  302. padding: 40px 20px;
  303. color: var(--text-secondary);
  304. }
  305. .loading-spinner {
  306. display: inline-block;
  307. width: 32px;
  308. height: 32px;
  309. border: 3px solid var(--border-color);
  310. border-radius: 50%;
  311. border-top-color: var(--tab-border);
  312. animation: spin 1s ease-in-out infinite;
  313. margin-bottom: 15px;
  314. }
  315. /* Empty state */
  316. .empty-state {
  317. text-align: center;
  318. padding: 60px 20px;
  319. color: var(--text-secondary);
  320. }
  321. .empty-state h3 {
  322. color: var(--text-primary);
  323. margin: 15px 0 10px 0;
  324. transition: color 0.3s ease;
  325. }
  326. .empty-state p {
  327. margin: 0;
  328. font-size: 0.9rem;
  329. }
  330. .empty-state svg {
  331. margin-bottom: 15px;
  332. }
  333. /* Responsive design */
  334. @media (max-width: 768px) {
  335. .admin-container {
  336. margin: 10px;
  337. max-width: none;
  338. }
  339. .header-controls {
  340. position: relative;
  341. top: 15px;
  342. right: auto;
  343. justify-content: center;
  344. margin-top: 15px;
  345. }
  346. .stats-container {
  347. grid-template-columns: 1fr;
  348. gap: 10px;
  349. }
  350. .section-header {
  351. flex-direction: column;
  352. align-items: stretch;
  353. }
  354. .search-container {
  355. min-width: auto;
  356. }
  357. /* Make table horizontally scrollable on mobile */
  358. .table-container {
  359. overflow-x: auto;
  360. }
  361. .users-table {
  362. min-width: 700px;
  363. }
  364. .users-table th,
  365. .users-table td {
  366. padding: 10px 8px;
  367. white-space: nowrap;
  368. }
  369. .roles {
  370. flex-direction: column;
  371. gap: 3px;
  372. }
  373. .action-buttons {
  374. flex-direction: column;
  375. gap: 3px;
  376. }
  377. }
  378. @media (max-width: 480px) {
  379. .users-section {
  380. padding: 15px;
  381. }
  382. .admin-controls {
  383. padding: 15px;
  384. }
  385. .stat-card {
  386. padding: 15px;
  387. }
  388. .stat-card h3 {
  389. font-size: 1.5rem;
  390. }
  391. }
  392. /* Edit User Modal */
  393. .modal {
  394. position: fixed;
  395. top: 0;
  396. left: 0;
  397. width: 100%;
  398. height: 100%;
  399. background: rgba(0, 0, 0, 0.6);
  400. display: flex;
  401. align-items: center;
  402. justify-content: center;
  403. z-index: 1000;
  404. backdrop-filter: blur(4px);
  405. }
  406. .modal-content {
  407. background: var(--container-bg);
  408. border-radius: 15px;
  409. box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
  410. width: 100%;
  411. max-width: 500px;
  412. max-height: 90vh;
  413. overflow-y: auto;
  414. margin: 20px;
  415. transition: all 0.3s ease;
  416. }
  417. .modal-header {
  418. display: flex;
  419. justify-content: space-between;
  420. align-items: center;
  421. padding: 25px 30px 20px;
  422. border-bottom: 1px solid var(--border-color);
  423. }
  424. .modal-header h3 {
  425. margin: 0;
  426. color: var(--text-primary);
  427. font-size: 1.4rem;
  428. transition: color 0.3s ease;
  429. }
  430. .close-btn {
  431. background: none;
  432. border: none;
  433. color: var(--text-secondary);
  434. cursor: pointer;
  435. padding: 5px;
  436. border-radius: 50%;
  437. transition: all 0.3s ease;
  438. display: flex;
  439. align-items: center;
  440. justify-content: center;
  441. font-size: 24px;
  442. line-height: 1;
  443. }
  444. .close-btn:hover {
  445. background: var(--section-bg);
  446. color: var(--text-primary);
  447. transform: scale(1.1);
  448. }
  449. .form-section {
  450. padding: 20px 30px;
  451. border-bottom: 1px solid var(--border-color);
  452. }
  453. .form-section:last-of-type {
  454. border-bottom: none;
  455. }
  456. .section-label {
  457. display: block;
  458. font-weight: 600;
  459. color: var(--text-primary);
  460. margin-bottom: 15px;
  461. font-size: 1rem;
  462. transition: color 0.3s ease;
  463. }
  464. /* Toggle Switch */
  465. .toggle-switch {
  466. display: flex;
  467. align-items: center;
  468. gap: 12px;
  469. cursor: pointer;
  470. padding: 8px 0;
  471. }
  472. .toggle-switch input[type="checkbox"] {
  473. display: none;
  474. }
  475. .toggle-slider {
  476. position: relative;
  477. width: 50px;
  478. height: 24px;
  479. background: var(--border-color);
  480. border-radius: 24px;
  481. transition: all 0.3s ease;
  482. }
  483. .toggle-slider::before {
  484. content: '';
  485. position: absolute;
  486. top: 2px;
  487. left: 2px;
  488. width: 20px;
  489. height: 20px;
  490. background: white;
  491. border-radius: 50%;
  492. transition: all 0.3s ease;
  493. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  494. }
  495. .toggle-switch input[type="checkbox"]:checked + .toggle-slider {
  496. background: var(--tab-border);
  497. }
  498. .toggle-switch input[type="checkbox"]:checked + .toggle-slider::before {
  499. transform: translateX(26px);
  500. }
  501. .toggle-label {
  502. color: var(--text-primary);
  503. font-weight: 500;
  504. transition: color 0.3s ease;
  505. }
  506. /* Role Checkboxes */
  507. .roles-grid {
  508. display: grid;
  509. grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  510. gap: 12px;
  511. }
  512. .role-checkbox {
  513. display: flex;
  514. align-items: center;
  515. gap: 10px;
  516. cursor: pointer;
  517. padding: 12px;
  518. border: 2px solid var(--border-color);
  519. border-radius: 8px;
  520. transition: all 0.3s ease;
  521. background: var(--user-details-bg);
  522. }
  523. .role-checkbox:hover {
  524. border-color: var(--tab-border);
  525. background: var(--section-bg);
  526. }
  527. .role-checkbox input[type="checkbox"] {
  528. display: none;
  529. }
  530. .role-checkmark {
  531. width: 18px;
  532. height: 18px;
  533. border: 2px solid var(--border-color);
  534. border-radius: 4px;
  535. position: relative;
  536. transition: all 0.3s ease;
  537. flex-shrink: 0;
  538. }
  539. .role-checkmark::after {
  540. content: '';
  541. position: absolute;
  542. top: 2px;
  543. left: 5px;
  544. width: 4px;
  545. height: 8px;
  546. border: solid white;
  547. border-width: 0 2px 2px 0;
  548. transform: rotate(45deg);
  549. opacity: 0;
  550. transition: opacity 0.3s ease;
  551. }
  552. .role-checkbox input[type="checkbox"]:checked + .role-checkmark {
  553. background: var(--tab-border);
  554. border-color: var(--tab-border);
  555. }
  556. .role-checkbox input[type="checkbox"]:checked + .role-checkmark::after {
  557. opacity: 1;
  558. }
  559. .role-name {
  560. font-size: 0.85rem;
  561. font-weight: 500;
  562. color: var(--text-primary);
  563. text-transform: uppercase;
  564. letter-spacing: 0.5px;
  565. transition: color 0.3s ease;
  566. }
  567. /* Modal Buttons */
  568. .modal-buttons {
  569. display: flex;
  570. gap: 12px;
  571. padding: 25px 30px;
  572. justify-content: flex-end;
  573. }
  574. .btn-primary, .btn-secondary {
  575. padding: 12px 24px;
  576. border: none;
  577. border-radius: 8px;
  578. font-weight: 600;
  579. cursor: pointer;
  580. transition: all 0.3s ease;
  581. font-size: 0.9rem;
  582. }
  583. .btn-primary {
  584. background: var(--button-gradient);
  585. color: var(--button-text);
  586. }
  587. .btn-primary:hover {
  588. transform: translateY(-2px);
  589. box-shadow: 0 5px 15px var(--button-hover-shadow);
  590. }
  591. .btn-primary:disabled {
  592. background: var(--button-disabled-bg);
  593. cursor: not-allowed;
  594. transform: none;
  595. box-shadow: none;
  596. }
  597. .btn-secondary {
  598. background: var(--section-bg);
  599. color: var(--text-primary);
  600. border: 2px solid var(--border-color);
  601. }
  602. .btn-secondary:hover {
  603. background: var(--tab-active-bg);
  604. border-color: var(--tab-border);
  605. }
  606. /* Modal Message */
  607. .modal-message {
  608. margin-top: 15px;
  609. padding: 12px;
  610. border-radius: 6px;
  611. text-align: center;
  612. font-weight: 500;
  613. font-size: 0.9rem;
  614. }
  615. .modal-message.success {
  616. background: var(--message-success-bg);
  617. color: var(--message-success-text);
  618. border: 1px solid var(--message-success-border);
  619. }
  620. .modal-message.error {
  621. background: var(--message-error-bg);
  622. color: var(--message-error-text);
  623. border: 1px solid var(--message-error-border);
  624. }
  625. /* Mobile Modal Responsiveness */
  626. @media (max-width: 768px) {
  627. .modal-content {
  628. max-width: none;
  629. margin: 10px;
  630. max-height: 95vh;
  631. }
  632. .modal-header,
  633. .form-section,
  634. .modal-buttons {
  635. padding-left: 20px;
  636. padding-right: 20px;
  637. }
  638. .roles-grid {
  639. grid-template-columns: 1fr 1fr;
  640. gap: 8px;
  641. }
  642. .role-checkbox {
  643. padding: 10px;
  644. font-size: 0.8rem;
  645. }
  646. .modal-buttons {
  647. flex-direction: column;
  648. }
  649. }
  650. /* Dark theme adjustments */
  651. [data-theme="dark"] .modal {
  652. background: rgba(0, 0, 0, 0.8);
  653. }
  654. [data-theme="dark"] .modal-content {
  655. box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
  656. }
  657. [data-theme="dark"] .table-container {
  658. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
  659. }
  660. [data-theme="dark"] .stat-card {
  661. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
  662. }