Initial commit
This commit is contained in:
184
assets/css/admin.css
Normal file
184
assets/css/admin.css
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Door Status Voting - Admin Styles
|
||||
*/
|
||||
|
||||
.dsv-admin-wrap {
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.dsv-admin-wrap h1 {
|
||||
font-size: 28px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
/* Grid Layout */
|
||||
.dsv-admin-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.dsv-admin-card {
|
||||
background: white;
|
||||
border: 1px solid #ccd0d4;
|
||||
border-radius: 8px;
|
||||
padding: 20px 25px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.dsv-admin-card h2 {
|
||||
margin: 0 0 15px 0;
|
||||
padding: 0 0 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dsv-admin-card-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
/* Shortcode Display */
|
||||
.dsv-shortcode {
|
||||
display: block;
|
||||
background: #f0f0f1;
|
||||
padding: 12px 15px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
margin: 10px 0;
|
||||
user-select: all;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dsv-shortcode:hover {
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
/* Form Elements */
|
||||
#dsv-settings-form textarea {
|
||||
width: 100%;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#dsv-settings-form .button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.dsv-save-status {
|
||||
margin-left: 10px;
|
||||
color: #00a32a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Table Styles */
|
||||
.dsv-admin-card table {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.dsv-admin-card table th,
|
||||
.dsv-admin-card table td {
|
||||
padding: 12px 10px;
|
||||
}
|
||||
|
||||
/* Badges */
|
||||
.dsv-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dsv-badge-open {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
.dsv-badge-closed {
|
||||
background: #f44336;
|
||||
}
|
||||
|
||||
.dsv-badge-tied {
|
||||
background: #FF9800;
|
||||
}
|
||||
|
||||
.dsv-meta-empty {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* Meta-Status Buttons */
|
||||
.dsv-meta-buttons {
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.dsv-meta-set-btn {
|
||||
min-width: 28px;
|
||||
padding: 2px 5px !important;
|
||||
font-size: 12px !important;
|
||||
line-height: 1.4 !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.dsv-meta-set-btn.active {
|
||||
box-shadow: inset 0 0 0 2px #2271b1;
|
||||
background: #f0f6fc;
|
||||
}
|
||||
|
||||
/* Abweichung hervorheben */
|
||||
.dsv-mismatch {
|
||||
background: #fff3cd !important;
|
||||
}
|
||||
|
||||
.dsv-mismatch td {
|
||||
border-left-color: #FF9800;
|
||||
}
|
||||
|
||||
.dsv-mismatch td:first-child {
|
||||
border-left: 3px solid #FF9800;
|
||||
}
|
||||
|
||||
/* Disabled Label */
|
||||
.dsv-disabled-label {
|
||||
color: #d63638;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Action Buttons */
|
||||
.dsv-actions-cell {
|
||||
min-width: 280px;
|
||||
}
|
||||
|
||||
.dsv-action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.dsv-action-buttons .button {
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
height: auto;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.dsv-reset-type-btn {
|
||||
min-width: 85px;
|
||||
}
|
||||
|
||||
/* No Data */
|
||||
.dsv-no-data {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 782px) {
|
||||
.dsv-admin-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
550
assets/css/frontend.css
Normal file
550
assets/css/frontend.css
Normal file
@@ -0,0 +1,550 @@
|
||||
/* ============================================
|
||||
DOOR STATUS VOTING - FRONTEND STYLES
|
||||
Angepasst an Website-Design mit Elementor-Variablen
|
||||
============================================ */
|
||||
|
||||
:root {
|
||||
--dsv-primary: #2F4858;
|
||||
--dsv-text: #141F27;
|
||||
--dsv-accent: #C5422A;
|
||||
--dsv-bg: #F6F9FC;
|
||||
--dsv-white: #FFFFFF;
|
||||
--dsv-hover: #B33822;
|
||||
--dsv-border: #E0E5E9;
|
||||
--dsv-success: #4CAF50;
|
||||
--dsv-error: #C5422A;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
HAUPT-WIDGET
|
||||
============================================ */
|
||||
|
||||
.dsv-widget {
|
||||
background: var(--dsv-bg);
|
||||
border-radius: 12px;
|
||||
padding: 24px 28px;
|
||||
width: 100%;
|
||||
border: 1px solid var(--dsv-border);
|
||||
box-shadow: 0 4px 12px rgba(47, 72, 88, 0.06);
|
||||
font-family: var(--e-global-typography-text-font-family), Sans-serif;
|
||||
font-size: var(--e-global-typography-text-font-size);
|
||||
font-weight: var(--e-global-typography-text-font-weight);
|
||||
color: var(--e-global-color-text, var(--dsv-text));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Titel */
|
||||
.dsv-title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--dsv-primary);
|
||||
margin: 0 0 18px 0;
|
||||
}
|
||||
|
||||
/* Hauptzeile: Tür links, Voting rechts */
|
||||
.dsv-main-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
TÜR CONTAINER
|
||||
============================================ */
|
||||
|
||||
.dsv-door-container {
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 150px;
|
||||
flex-shrink: 0;
|
||||
perspective: 500px;
|
||||
}
|
||||
|
||||
/* Status Badge */
|
||||
.dsv-status-badge {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
z-index: 10;
|
||||
white-space: nowrap;
|
||||
transition: all 0.5s ease;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.dsv-status-open {
|
||||
background: linear-gradient(135deg, var(--dsv-success), #43A047);
|
||||
box-shadow: 0 3px 10px rgba(76, 175, 80, 0.35);
|
||||
}
|
||||
|
||||
.dsv-status-closed {
|
||||
background: linear-gradient(135deg, var(--dsv-accent), var(--dsv-hover));
|
||||
box-shadow: 0 3px 10px rgba(197, 66, 42, 0.35);
|
||||
}
|
||||
|
||||
.dsv-status-tied {
|
||||
background: linear-gradient(135deg, #FF9800, #F57C00);
|
||||
box-shadow: 0 3px 10px rgba(255, 152, 0, 0.35);
|
||||
}
|
||||
|
||||
/* Türrahmen */
|
||||
.dsv-door-frame {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 85px;
|
||||
height: 120px;
|
||||
background: linear-gradient(135deg, #5D4037 0%, #4E342E 100%);
|
||||
border-radius: 4px 4px 0 0;
|
||||
border: 4px solid #3E2723;
|
||||
border-bottom: 6px solid #3E2723;
|
||||
box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.5);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Licht hinter der Tür */
|
||||
.dsv-light {
|
||||
position: absolute;
|
||||
inset: 3px;
|
||||
border-radius: 2px;
|
||||
background: linear-gradient(180deg, #FFF9C4 0%, #FFEE58 50%, #FFC107 100%);
|
||||
opacity: 0;
|
||||
transition: opacity 0.7s ease;
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="open"] .dsv-light {
|
||||
opacity: 1;
|
||||
box-shadow: 0 0 35px 12px rgba(255, 235, 59, 0.3);
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="tied"] .dsv-light {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Lichtstrahlen */
|
||||
.dsv-light-rays {
|
||||
position: absolute;
|
||||
inset: 3px;
|
||||
overflow: hidden;
|
||||
border-radius: 2px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.7s ease;
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="open"] .dsv-light-rays,
|
||||
.dsv-widget[data-status="tied"] .dsv-light-rays {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dsv-ray {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 200, 0.4);
|
||||
filter: blur(1px);
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
.dsv-ray:nth-child(1) { left: 15%; }
|
||||
.dsv-ray:nth-child(2) { left: 30%; }
|
||||
.dsv-ray:nth-child(3) { left: 45%; }
|
||||
.dsv-ray:nth-child(4) { left: 60%; }
|
||||
.dsv-ray:nth-child(5) { left: 75%; }
|
||||
|
||||
/* ============================================
|
||||
DIE TÜR
|
||||
============================================ */
|
||||
|
||||
.dsv-door {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 71px;
|
||||
height: 106px;
|
||||
border-radius: 2px 2px 0 0;
|
||||
transform-origin: left center;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
background:
|
||||
linear-gradient(90deg,
|
||||
rgba(0,0,0,0.1) 0%,
|
||||
transparent 3%,
|
||||
transparent 97%,
|
||||
rgba(0,0,0,0.1) 100%
|
||||
),
|
||||
linear-gradient(180deg,
|
||||
#8D6E63 0%,
|
||||
#795548 15%,
|
||||
#8D6E63 30%,
|
||||
#6D4C41 50%,
|
||||
#795548 70%,
|
||||
#8D6E63 85%,
|
||||
#795548 100%
|
||||
);
|
||||
|
||||
box-shadow: 2px 0 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="open"] .dsv-door {
|
||||
transform: rotateY(-70deg);
|
||||
box-shadow: 4px 0 12px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="tied"] .dsv-door {
|
||||
transform: rotateY(-35deg);
|
||||
box-shadow: 3px 0 8px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="closed"] .dsv-door {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
|
||||
/* Holzmaserung */
|
||||
.dsv-door-grain {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 2px 2px 0 0;
|
||||
opacity: 0.15;
|
||||
background-image:
|
||||
repeating-linear-gradient(
|
||||
92deg,
|
||||
transparent,
|
||||
transparent 5px,
|
||||
rgba(0,0,0,0.1) 5px,
|
||||
rgba(0,0,0,0.1) 6px
|
||||
);
|
||||
}
|
||||
|
||||
/* Türpaneele */
|
||||
.dsv-door-panel {
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
border: 2px solid rgba(62, 39, 35, 0.4);
|
||||
border-radius: 2px;
|
||||
background: rgba(93, 64, 55, 0.2);
|
||||
}
|
||||
|
||||
.dsv-door-panel-top {
|
||||
top: 10px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.dsv-door-panel-bottom {
|
||||
bottom: 10px;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
/* Türklinke */
|
||||
.dsv-door-handle {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.dsv-handle-plate {
|
||||
width: 9px;
|
||||
height: 26px;
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(135deg, #FFD54F 0%, #FFA000 50%, #FF8F00 100%);
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.dsv-handle-lever {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: -1px;
|
||||
transform: translateY(-50%);
|
||||
width: 11px;
|
||||
height: 5px;
|
||||
border-radius: 0 2px 2px 0;
|
||||
background: linear-gradient(180deg, #FFD54F 0%, #FFA000 100%);
|
||||
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Schatten */
|
||||
.dsv-shadow {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 75px;
|
||||
height: 10px;
|
||||
background: radial-gradient(ellipse, rgba(0,0,0,0.2) 0%, transparent 70%);
|
||||
transition: all 0.7s ease;
|
||||
}
|
||||
|
||||
.dsv-widget[data-status="open"] .dsv-shadow {
|
||||
width: 90px;
|
||||
transform: translateX(-50%) scaleX(1.2);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
VOTING SECTION (rechte Seite)
|
||||
============================================ */
|
||||
|
||||
.dsv-voting-section {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Fortschrittsbalken */
|
||||
.dsv-progress-container {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.dsv-progress-bar {
|
||||
position: relative;
|
||||
height: 28px;
|
||||
background: var(--dsv-bg);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--dsv-border);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.dsv-progress-open {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, var(--dsv-success) 0%, #66BB6A 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-left: 12px;
|
||||
transition: width 0.7s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.dsv-progress-closed {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #EF5350 0%, var(--dsv-accent) 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding-right: 12px;
|
||||
transition: width 0.7s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.dsv-progress-count {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.dsv-progress-divider {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background: rgba(255,255,255,0.5);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.dsv-progress-labels {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: var(--e-global-typography-text-font-weight);
|
||||
}
|
||||
|
||||
.dsv-label-open {
|
||||
color: #388E3C;
|
||||
}
|
||||
|
||||
.dsv-label-closed {
|
||||
color: var(--dsv-accent);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
VOTING BUTTONS
|
||||
============================================ */
|
||||
|
||||
.dsv-buttons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.dsv-buttons.dsv-voted {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.dsv-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 12px 18px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-family: var(--e-global-typography-text-font-family), Sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.dsv-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.dsv-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.dsv-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.dsv-btn-open {
|
||||
background: linear-gradient(135deg, var(--dsv-success) 0%, #388E3C 100%);
|
||||
}
|
||||
|
||||
.dsv-btn-open:hover {
|
||||
box-shadow: 0 5px 15px rgba(76, 175, 80, 0.4);
|
||||
}
|
||||
|
||||
.dsv-btn-closed {
|
||||
background: linear-gradient(135deg, var(--dsv-accent) 0%, var(--dsv-hover) 100%);
|
||||
}
|
||||
|
||||
.dsv-btn-closed:hover {
|
||||
box-shadow: 0 5px 15px rgba(197, 66, 42, 0.4);
|
||||
}
|
||||
|
||||
.dsv-btn-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.dsv-btn-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Voted Message mit Remove Button */
|
||||
.dsv-voted-message {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.dsv-voted-open {
|
||||
background: #E8F5E9;
|
||||
color: #2E7D32;
|
||||
border-color: #A5D6A7;
|
||||
}
|
||||
|
||||
.dsv-voted-closed {
|
||||
background: #FFEBEE;
|
||||
color: var(--dsv-hover);
|
||||
border-color: #FFCDD2;
|
||||
}
|
||||
|
||||
.dsv-voted-icon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Remove Vote Button */
|
||||
.dsv-remove-vote {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: inherit;
|
||||
opacity: 0.5;
|
||||
cursor: pointer;
|
||||
padding: 4px 8px;
|
||||
margin-left: 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.dsv-remove-vote:hover {
|
||||
opacity: 1;
|
||||
background: rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
INFO TEXT
|
||||
============================================ */
|
||||
|
||||
.dsv-info {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
margin: 12px 0 0 0;
|
||||
font-weight: var(--e-global-typography-text-font-weight);
|
||||
}
|
||||
|
||||
.dsv-total {
|
||||
font-weight: 600;
|
||||
color: var(--dsv-primary);
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
ANIMATIONEN
|
||||
============================================ */
|
||||
|
||||
.dsv-widget.dsv-animating .dsv-door {
|
||||
transition: transform 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
}
|
||||
|
||||
@keyframes dsv-pulse {
|
||||
0% { transform: translateX(-50%) scale(1); }
|
||||
50% { transform: translateX(-50%) scale(1.08); }
|
||||
100% { transform: translateX(-50%) scale(1); }
|
||||
}
|
||||
|
||||
.dsv-widget.dsv-just-voted .dsv-status-badge {
|
||||
animation: dsv-pulse 0.5s ease;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
RESPONSIVE
|
||||
============================================ */
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.dsv-widget {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dsv-main-row {
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.dsv-door-container {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.dsv-voting-section {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dsv-btn {
|
||||
padding: 11px 14px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.dsv-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
259
assets/js/admin.js
Normal file
259
assets/js/admin.js
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* Door Status Voting - Admin JavaScript
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
$(document).ready(function() {
|
||||
initSettingsForm();
|
||||
initResetButtons();
|
||||
initResetByTypeButtons();
|
||||
initMismatchFilter();
|
||||
initMetaStatusButtons();
|
||||
});
|
||||
|
||||
/**
|
||||
* Settings Form Handler
|
||||
*/
|
||||
function initSettingsForm() {
|
||||
$('#dsv-settings-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $form = $(this);
|
||||
var $btn = $form.find('.button-primary');
|
||||
var $status = $form.find('.dsv-save-status');
|
||||
|
||||
$btn.prop('disabled', true).text('Speichern...');
|
||||
$status.text('');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: dsvAdmin.ajaxUrl,
|
||||
data: {
|
||||
action: 'dsv_save_settings',
|
||||
nonce: dsvAdmin.nonce,
|
||||
disabled_posts: $('#dsv-disabled-posts').val()
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$status.text('✓ Gespeichert').css('color', '#00a32a');
|
||||
} else {
|
||||
$status.text('✗ Fehler: ' + (response.data?.message || 'Unbekannt')).css('color', '#d63638');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$status.text('✗ Verbindungsfehler').css('color', '#d63638');
|
||||
},
|
||||
complete: function() {
|
||||
$btn.prop('disabled', false).text('Einstellungen speichern');
|
||||
|
||||
setTimeout(function() {
|
||||
$status.fadeOut(300, function() {
|
||||
$(this).text('').show();
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset All Buttons Handler
|
||||
*/
|
||||
function initResetButtons() {
|
||||
$(document).on('click', '.dsv-reset-btn', function() {
|
||||
var $btn = $(this);
|
||||
var $row = $btn.closest('tr');
|
||||
var postId = $btn.data('post-id');
|
||||
|
||||
if (!confirm('Alle Votes für diesen Beitrag wirklich zurücksetzen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$btn.prop('disabled', true).text('Löschen...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: dsvAdmin.ajaxUrl,
|
||||
data: {
|
||||
action: 'dsv_reset_votes',
|
||||
nonce: dsvAdmin.nonce,
|
||||
post_id: postId
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$row.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
checkEmptyTable();
|
||||
});
|
||||
} else {
|
||||
alert('Fehler: ' + (response.data?.message || 'Unbekannt'));
|
||||
$btn.prop('disabled', false).text('Alle löschen');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Verbindungsfehler');
|
||||
$btn.prop('disabled', false).text('Alle löschen');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset By Type Buttons Handler
|
||||
*/
|
||||
function initResetByTypeButtons() {
|
||||
$(document).on('click', '.dsv-reset-type-btn', function() {
|
||||
var $btn = $(this);
|
||||
var $row = $btn.closest('tr');
|
||||
var postId = $btn.data('post-id');
|
||||
var type = $btn.data('type');
|
||||
var typeLabel = type === 'open' ? 'Geöffnet' : 'Geschlossen';
|
||||
|
||||
if (!confirm('Alle "' + typeLabel + '" Stimmen für diesen Beitrag löschen?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalText = $btn.text();
|
||||
$btn.prop('disabled', true).text('...');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: dsvAdmin.ajaxUrl,
|
||||
data: {
|
||||
action: 'dsv_reset_votes_by_type',
|
||||
nonce: dsvAdmin.nonce,
|
||||
post_id: postId,
|
||||
type: type
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Zähler aktualisieren
|
||||
$row.find('.dsv-count-open').text(response.data.votes.open);
|
||||
$row.find('.dsv-count-closed').text(response.data.votes.closed);
|
||||
$row.find('.dsv-count-total').text(response.data.votes.open + response.data.votes.closed);
|
||||
|
||||
// Status Badge aktualisieren
|
||||
var $badge = $row.find('.dsv-badge');
|
||||
$badge.removeClass('dsv-badge-open dsv-badge-closed dsv-badge-tied');
|
||||
|
||||
if (response.data.votes.open > response.data.votes.closed) {
|
||||
$badge.addClass('dsv-badge-open').text('Geöffnet');
|
||||
} else if (response.data.votes.closed > response.data.votes.open) {
|
||||
$badge.addClass('dsv-badge-closed').text('Geschlossen');
|
||||
} else {
|
||||
$badge.addClass('dsv-badge-tied').text('Unklar');
|
||||
}
|
||||
|
||||
// Wenn keine Votes mehr, Zeile entfernen
|
||||
if (response.data.votes.open === 0 && response.data.votes.closed === 0) {
|
||||
$row.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
checkEmptyTable();
|
||||
});
|
||||
} else {
|
||||
// Kurzes Feedback
|
||||
$btn.text('✓').css('color', '#00a32a');
|
||||
setTimeout(function() {
|
||||
$btn.prop('disabled', false).text(originalText).css('color', '');
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
alert('Fehler: ' + (response.data?.message || 'Unbekannt'));
|
||||
$btn.prop('disabled', false).text(originalText);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Verbindungsfehler');
|
||||
$btn.prop('disabled', false).text(originalText);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter: Nur Abweichungen anzeigen
|
||||
*/
|
||||
function initMismatchFilter() {
|
||||
var $btn = $('#dsv-filter-mismatch');
|
||||
var active = false;
|
||||
|
||||
$btn.on('click', function() {
|
||||
active = !active;
|
||||
var $table = $('#dsv-votes-table');
|
||||
|
||||
if (active) {
|
||||
$table.find('tbody tr').not('.dsv-mismatch').hide();
|
||||
$btn.addClass('button-primary').text('Alle anzeigen');
|
||||
} else {
|
||||
$table.find('tbody tr').show();
|
||||
$btn.removeClass('button-primary').text('Nur Abweichungen anzeigen');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Meta-Status per Knopfdruck ändern
|
||||
*/
|
||||
function initMetaStatusButtons() {
|
||||
$(document).on('click', '.dsv-meta-set-btn', function() {
|
||||
var $btn = $(this);
|
||||
var $cell = $btn.closest('.dsv-meta-status-cell');
|
||||
var postId = $btn.data('post-id');
|
||||
var status = $btn.data('status');
|
||||
|
||||
$cell.find('.dsv-meta-set-btn').prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: dsvAdmin.ajaxUrl,
|
||||
data: {
|
||||
action: 'dsv_update_meta_status',
|
||||
nonce: dsvAdmin.nonce,
|
||||
post_id: postId,
|
||||
status: status
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
// Badge aktualisieren
|
||||
var badgeClass = 'dsv-badge-tied';
|
||||
var lower = status.toLowerCase();
|
||||
if (lower === 'geöffnet') badgeClass = 'dsv-badge-open';
|
||||
else if (lower === 'geschlossen') badgeClass = 'dsv-badge-closed';
|
||||
|
||||
var $badge = $cell.find('.dsv-badge, .dsv-meta-empty');
|
||||
if ($badge.hasClass('dsv-meta-empty')) {
|
||||
$badge.removeClass('dsv-meta-empty').addClass('dsv-badge');
|
||||
}
|
||||
$badge.removeClass('dsv-badge-open dsv-badge-closed dsv-badge-tied')
|
||||
.addClass(badgeClass)
|
||||
.text(status);
|
||||
|
||||
// Active-State der Buttons
|
||||
$cell.find('.dsv-meta-set-btn').removeClass('active');
|
||||
$btn.addClass('active');
|
||||
} else {
|
||||
alert('Fehler: ' + (response.data?.message || 'Unbekannt'));
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Verbindungsfehler');
|
||||
},
|
||||
complete: function() {
|
||||
$cell.find('.dsv-meta-set-btn').prop('disabled', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüfen ob Tabelle leer ist
|
||||
*/
|
||||
function checkEmptyTable() {
|
||||
if ($('tbody tr').length === 0) {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
257
assets/js/frontend.js
Normal file
257
assets/js/frontend.js
Normal file
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* Door Status Voting - Frontend JavaScript
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initDoorVoting();
|
||||
});
|
||||
|
||||
function initDoorVoting() {
|
||||
const widgets = document.querySelectorAll('.dsv-widget');
|
||||
|
||||
widgets.forEach(function(widget) {
|
||||
// Vote Buttons
|
||||
const buttons = widget.querySelectorAll('.dsv-btn');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
handleVote(widget, btn.dataset.vote);
|
||||
});
|
||||
});
|
||||
|
||||
// Remove Vote Button
|
||||
const removeBtn = widget.querySelector('.dsv-remove-vote');
|
||||
if (removeBtn) {
|
||||
removeBtn.addEventListener('click', function() {
|
||||
handleRemoveVote(widget);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleVote(widget, vote) {
|
||||
const postId = widget.dataset.postId;
|
||||
const hasVoted = widget.dataset.hasVoted === 'true';
|
||||
|
||||
if (hasVoted) return;
|
||||
|
||||
// Buttons deaktivieren
|
||||
const buttons = widget.querySelectorAll('.dsv-btn');
|
||||
buttons.forEach(function(btn) {
|
||||
btn.disabled = true;
|
||||
});
|
||||
|
||||
// Animation starten
|
||||
widget.classList.add('dsv-animating');
|
||||
|
||||
// AJAX Request
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'dsv_vote');
|
||||
formData.append('post_id', postId);
|
||||
formData.append('vote', vote);
|
||||
formData.append('nonce', dsvConfig.nonce);
|
||||
|
||||
fetch(dsvConfig.ajaxUrl, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data) {
|
||||
if (data.success) {
|
||||
updateWidget(widget, data.data, vote);
|
||||
} else {
|
||||
console.error('Vote error:', data.data?.message);
|
||||
buttons.forEach(function(btn) {
|
||||
btn.disabled = false;
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Network error:', error);
|
||||
buttons.forEach(function(btn) {
|
||||
btn.disabled = false;
|
||||
});
|
||||
})
|
||||
.finally(function() {
|
||||
widget.classList.remove('dsv-animating');
|
||||
});
|
||||
}
|
||||
|
||||
function handleRemoveVote(widget) {
|
||||
const postId = widget.dataset.postId;
|
||||
|
||||
// Button deaktivieren
|
||||
const removeBtn = widget.querySelector('.dsv-remove-vote');
|
||||
if (removeBtn) {
|
||||
removeBtn.disabled = true;
|
||||
removeBtn.textContent = '...';
|
||||
}
|
||||
|
||||
widget.classList.add('dsv-animating');
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'dsv_remove_vote');
|
||||
formData.append('post_id', postId);
|
||||
formData.append('nonce', dsvConfig.nonce);
|
||||
|
||||
fetch(dsvConfig.ajaxUrl, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
credentials: 'same-origin'
|
||||
})
|
||||
.then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data) {
|
||||
if (data.success) {
|
||||
resetWidgetToVoting(widget, data.data);
|
||||
} else {
|
||||
console.error('Remove vote error:', data.data?.message);
|
||||
if (removeBtn) {
|
||||
removeBtn.disabled = false;
|
||||
removeBtn.textContent = '✕';
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('Network error:', error);
|
||||
if (removeBtn) {
|
||||
removeBtn.disabled = false;
|
||||
removeBtn.textContent = '✕';
|
||||
}
|
||||
})
|
||||
.finally(function() {
|
||||
widget.classList.remove('dsv-animating');
|
||||
});
|
||||
}
|
||||
|
||||
function updateWidget(widget, data, userVote) {
|
||||
// Status aktualisieren
|
||||
widget.dataset.status = data.status;
|
||||
widget.dataset.hasVoted = 'true';
|
||||
widget.dataset.userVote = userVote;
|
||||
|
||||
// Badge aktualisieren
|
||||
const badge = widget.querySelector('.dsv-status-badge');
|
||||
badge.className = 'dsv-status-badge dsv-status-' + data.status;
|
||||
|
||||
if (data.status === 'open') {
|
||||
badge.innerHTML = '🟢 GEÖFFNET';
|
||||
} else if (data.status === 'closed') {
|
||||
badge.innerHTML = '🔴 GESCHLOSSEN';
|
||||
} else {
|
||||
badge.innerHTML = '🟡 UNKLAR';
|
||||
}
|
||||
|
||||
// Fortschrittsbalken aktualisieren
|
||||
updateProgressBar(widget, data);
|
||||
|
||||
// Buttons durch Bestätigung ersetzen
|
||||
const buttonsContainer = widget.querySelector('.dsv-buttons');
|
||||
buttonsContainer.classList.add('dsv-voted');
|
||||
|
||||
const voteClass = userVote === 'open' ? 'dsv-voted-open' : 'dsv-voted-closed';
|
||||
const voteIcon = userVote === 'open' ? '✓' : '✗';
|
||||
const voteText = userVote === 'open' ? 'Geöffnet' : 'Geschlossen';
|
||||
|
||||
buttonsContainer.innerHTML =
|
||||
'<div class="dsv-voted-message ' + voteClass + '">' +
|
||||
'<span class="dsv-voted-icon">' + voteIcon + '</span>' +
|
||||
'<span class="dsv-voted-text">Du hast für "' + voteText + '" gestimmt</span>' +
|
||||
'<button type="button" class="dsv-remove-vote" title="Stimme zurücknehmen">✕</button>' +
|
||||
'</div>';
|
||||
|
||||
// Event Listener für neuen Remove Button
|
||||
const newRemoveBtn = buttonsContainer.querySelector('.dsv-remove-vote');
|
||||
newRemoveBtn.addEventListener('click', function() {
|
||||
handleRemoveVote(widget);
|
||||
});
|
||||
|
||||
// Total aktualisieren
|
||||
widget.querySelector('.dsv-total').textContent = data.total;
|
||||
|
||||
// Pulse Animation
|
||||
widget.classList.add('dsv-just-voted');
|
||||
setTimeout(function() {
|
||||
widget.classList.remove('dsv-just-voted');
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function resetWidgetToVoting(widget, data) {
|
||||
// Status aktualisieren
|
||||
widget.dataset.status = data.status;
|
||||
widget.dataset.hasVoted = 'false';
|
||||
widget.dataset.userVote = '';
|
||||
|
||||
// Badge aktualisieren
|
||||
const badge = widget.querySelector('.dsv-status-badge');
|
||||
badge.className = 'dsv-status-badge dsv-status-' + data.status;
|
||||
|
||||
if (data.status === 'open') {
|
||||
badge.innerHTML = '🟢 GEÖFFNET';
|
||||
} else if (data.status === 'closed') {
|
||||
badge.innerHTML = '🔴 GESCHLOSSEN';
|
||||
} else {
|
||||
badge.innerHTML = '🟡 UNKLAR';
|
||||
}
|
||||
|
||||
// Fortschrittsbalken aktualisieren
|
||||
updateProgressBar(widget, data);
|
||||
|
||||
// Voting Buttons wieder anzeigen
|
||||
const buttonsContainer = widget.querySelector('.dsv-buttons');
|
||||
buttonsContainer.classList.remove('dsv-voted');
|
||||
|
||||
buttonsContainer.innerHTML =
|
||||
'<button type="button" class="dsv-btn dsv-btn-open" data-vote="open">' +
|
||||
'<span class="dsv-btn-icon">✓</span>' +
|
||||
'<span class="dsv-btn-text">Geöffnet</span>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="dsv-btn dsv-btn-closed" data-vote="closed">' +
|
||||
'<span class="dsv-btn-icon">✗</span>' +
|
||||
'<span class="dsv-btn-text">Geschlossen</span>' +
|
||||
'</button>';
|
||||
|
||||
// Event Listener für neue Buttons
|
||||
const newButtons = buttonsContainer.querySelectorAll('.dsv-btn');
|
||||
newButtons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
handleVote(widget, btn.dataset.vote);
|
||||
});
|
||||
});
|
||||
|
||||
// Total aktualisieren
|
||||
widget.querySelector('.dsv-total').textContent = data.total;
|
||||
}
|
||||
|
||||
function updateProgressBar(widget, data) {
|
||||
const progressOpen = widget.querySelector('.dsv-progress-open');
|
||||
const progressClosed = widget.querySelector('.dsv-progress-closed');
|
||||
|
||||
progressOpen.style.width = data.openPercent + '%';
|
||||
progressClosed.style.width = (100 - data.openPercent) + '%';
|
||||
|
||||
// Zähler
|
||||
if (data.openPercent > 15) {
|
||||
progressOpen.innerHTML = '<span class="dsv-progress-count">' + data.votes.open + '</span>';
|
||||
} else {
|
||||
progressOpen.innerHTML = '';
|
||||
}
|
||||
|
||||
if ((100 - data.openPercent) > 15) {
|
||||
progressClosed.innerHTML = '<span class="dsv-progress-count">' + data.votes.closed + '</span>';
|
||||
} else {
|
||||
progressClosed.innerHTML = '';
|
||||
}
|
||||
|
||||
// Labels
|
||||
widget.querySelector('.dsv-label-open').textContent = 'Geöffnet (' + data.openPercent + '%)';
|
||||
widget.querySelector('.dsv-label-closed').textContent = 'Geschlossen (' + (100 - data.openPercent) + '%)';
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user