estelam ticket, varizha , others
This commit is contained in:
1 parent
35a1ec1794
commit
6b546aad76
71 files changed
+2865
-191
No files matched your search
@@ -35,6 +35,13 @@
|
||||
.chaharsu-dock a.active{background:#0b4c8c}.chaharsu-dock a{min-height:52px;color:#cadbea}
|
||||
|
||||
/* Staff payment workspace: one reading order across desktop and mobile. */
|
||||
.pay-day-summary{--day-ink:var(--color-ink,#08376b);--day-line:#dce5ed;--day-muted:#526c86;margin-block:0 16px;padding:12px;border:1px solid var(--day-line);border-radius:20px;background:var(--color-paper,#fff);color:var(--day-ink)}
|
||||
.pay-day-head{display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:4px 12px;margin-bottom:8px}.pay-day-head h2{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 12px;margin:0;font-size:1rem;font-weight:800}.pay-day-head time,.pay-day-head>span{font-size:.75rem;font-weight:400;color:var(--day-muted)}
|
||||
.pay-day-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.pay-day-metric{min-width:0;padding:8px 12px;border-radius:12px;background:#f6f8fa}.pay-day-metric dt{font-size:.875rem;font-weight:700;line-height:1.7}.pay-day-metric dd{margin:0;overflow-wrap:anywhere}.pay-day-count{font-size:1.375rem;font-weight:900;line-height:1.6;font-variant-numeric:tabular-nums}.pay-day-count span{font-size:.75rem;font-weight:400;color:var(--day-muted)}.pay-day-amount{font-size:.875rem;font-weight:700;line-height:1.8;font-variant-numeric:tabular-nums}.pay-day-amount bdi{overflow-wrap:anywhere}.pay-day-amount span{font-weight:400}.pay-day-note{font-size:.75rem;line-height:1.8;color:var(--day-muted)}
|
||||
.pay-day-approved dt{color:#216345}.pay-day-rejected dt{color:#9f1f1f}.pay-day-pending{background:#fff8eb}.pay-day-pending dt{color:#805300}.pay-day-notices{grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px}.pay-day-notices dt{grid-column:1;grid-row:1}.pay-day-notices .pay-day-count{grid-column:2;grid-row:1/3}.pay-day-notices .pay-day-note{grid-column:1}
|
||||
.pay-day-definitions{margin-top:4px}.pay-day-definitions summary{width:fit-content;min-height:44px;display:flex;align-items:center;gap:8px;cursor:pointer;font-size:.875rem;font-weight:700;list-style:none}.pay-day-definitions summary::-webkit-details-marker{display:none}.pay-day-definitions summary::after{content:'+'}.pay-day-definitions[open] summary::after{content:'−'}.pay-day-definitions summary:focus-visible{outline:3px solid #1977ce;outline-offset:3px;border-radius:4px}.pay-day-definitions p{margin:0 0 8px;font-size:.875rem;line-height:1.8;color:var(--day-muted)}
|
||||
@media(min-width:640px){.pay-day-summary{padding:16px}.pay-day-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.pay-day-notices{grid-column:auto;display:block}}
|
||||
@media(min-width:1000px){.pay-day-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}
|
||||
.pay-workspace{max-width:1200px}.pay-page-head{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;margin-bottom:24px}
|
||||
.pay-page-title{display:flex;align-items:center;gap:14px;min-width:0;flex:1}.pay-page-title>div{min-width:0}.pay-page-title h1{font-size:24px;line-height:1.6;margin:0}.pay-page-title p{margin:4px 0 0;color:#526c86;font-size:14px}
|
||||
.pay-page-icon{display:grid;place-items:center;width:52px;height:52px;flex-shrink:0;border:1px solid #cde6f7;border-radius:16px;background:#e5f4ff;color:#08376b}.pay-page-icon .cs-icon{width:26px;height:26px}
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
/* Scoped to group dispatch pages; the staff shell and ticket conversation keep their own styles. */
|
||||
.dispatch-response-banner { padding: 24px; margin: 16px 0; background: #fff; border: 1px solid #dce5ed; border-radius: 16px; color: #08376b; }
|
||||
.dispatch-response-banner p, .dispatch-response-options p, .opening-sms-preview { font-size: 14px; line-height: 1.9; overflow-wrap: anywhere; }
|
||||
.dispatch-response-options fieldset { margin: 16px; padding: 16px; border: 1px solid #dce5ed; border-radius: 12px; }
|
||||
.dispatch-response-options fieldset label, .dispatch-sms-choice { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 8px; }
|
||||
.dispatch-response-options input[type="radio"], .dispatch-response-options input[type="checkbox"] { width: 20px; height: 20px; min-height: 20px; flex: 0 0 auto; }
|
||||
.dispatch-response-options > p, .dispatch-response-options > small, .dispatch-sms-choice { margin: 12px 16px; }
|
||||
.dispatch-open-confirm { max-width: 900px; margin: auto; }
|
||||
.opening-sms-preview { padding: 20px; margin: 16px 0; background: #f6fbff; border-inline-start: 3px solid #1977ce; }
|
||||
.dispatch-opening-actions { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.dispatch-workspace {
|
||||
--dispatch-ink: #08376b;
|
||||
--dispatch-muted: #526c86;
|
||||
--dispatch-line: #dce5ed;
|
||||
--dispatch-soft: #f6f9fc;
|
||||
color: var(--dispatch-ink);
|
||||
font-size: 1rem;
|
||||
gap: 1.25rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
.dispatch-workspace *, .dispatch-workspace *::before, .dispatch-workspace *::after { box-sizing: border-box; }
|
||||
.dispatch-workspace [hidden] { display: none !important; }
|
||||
.dispatch-workspace h1, .dispatch-workspace h2, .dispatch-workspace h3, .dispatch-workspace p { overflow-wrap: anywhere; }
|
||||
.dispatch-workspace :is(span, small, dt, dd) { overflow-wrap: anywhere; }
|
||||
.dispatch-workspace .dispatch-icon { width: 1.25rem; height: 1.25rem; flex: none; vertical-align: middle; }
|
||||
.dispatch-workspace a, .dispatch-workspace button, .dispatch-workspace input, .dispatch-workspace select, .dispatch-workspace textarea, .dispatch-workspace summary { -webkit-tap-highlight-color: transparent; }
|
||||
.dispatch-workspace :is(a, button, input, select, textarea, summary):focus-visible { outline: 3px solid #1977ce; outline-offset: 3px; }
|
||||
.dispatch-workspace .dispatch-eyebrow { margin: 0 0 .35rem; color: var(--dispatch-muted); font-size: .75rem; font-weight: 700; }
|
||||
.dispatch-page-heading { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
|
||||
.dispatch-page-heading h1 { margin: 0; font-size: 1.75rem; font-weight: 900; line-height: 1.5; }
|
||||
.dispatch-page-heading p:not(.dispatch-eyebrow) { margin: .45rem 0 0; color: var(--dispatch-muted); font-size: .875rem; line-height: 1.8; }
|
||||
.dispatch-privacy { display: flex; align-items: center; gap: .6rem; max-width: 18rem; border: 1px solid #c9e2d5; border-radius: .75rem; padding: .75rem; color: #166347; background: #f2faf6; font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-summary-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--dispatch-line); border-radius: 1.25rem; background: #fff; padding: 1rem 0; }
|
||||
.dispatch-summary-strip > div { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; padding: 0 1.25rem; }
|
||||
.dispatch-summary-strip > div + div { border-inline-start: 1px solid var(--dispatch-line); }
|
||||
.dispatch-summary-strip span { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.7; }
|
||||
.dispatch-summary-strip strong { font-size: 1.5rem; font-weight: 900; }
|
||||
.dispatch-view-switch { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; border-bottom: 1px solid #c6d4e0; padding-bottom: .75rem; }
|
||||
.dispatch-view-switch a { display: inline-flex; align-items: center; gap: .5rem; min-height: 2.75rem; border: 1px solid transparent; border-radius: .75rem; padding: .6rem 1rem; color: var(--dispatch-ink); font-size: .875rem; font-weight: 800; text-decoration: none; }
|
||||
.dispatch-view-switch a[aria-current="true"] { border-color: var(--dispatch-ink); background: var(--dispatch-ink); color: #fff; }
|
||||
.dispatch-view-switch a:not([aria-current="true"]):hover { background: #fff; border-color: var(--dispatch-line); }
|
||||
.dispatch-view-switch a > span { border-radius: 1rem; padding: .1rem .5rem; background: #e5f4ff; color: var(--dispatch-ink); font-size: .75rem; }
|
||||
.dispatch-compose-layout { display: grid; grid-template-columns: minmax(0, 1fr) 17rem; align-items: start; gap: 1.25rem; }
|
||||
.dispatch-workspace .dispatch-composer { gap: 1rem; min-width: 0; }
|
||||
.dispatch-workspace .dispatch-composer > section { border-color: var(--dispatch-line); border-radius: 1.25rem; box-shadow: none; }
|
||||
.dispatch-workspace .dispatch-composer > section > header { padding: 1.25rem; background: #fff; }
|
||||
.dispatch-workspace .dispatch-composer > section > header > span { width: 2.25rem; height: 2.25rem; background: #e5f4ff; color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-composer h2 { font-size: 1.125rem; font-weight: 900; }
|
||||
.dispatch-workspace .dispatch-composer header p { margin: .3rem 0 0; color: var(--dispatch-muted); font-size: .875rem; line-height: 1.7; }
|
||||
.dispatch-workspace .editor-grid { gap: 1rem; padding: 1.25rem; }
|
||||
.dispatch-workspace .editor-grid label, .dispatch-workspace .message-editor { gap: .5rem; font-size: .875rem; font-weight: 700; color: var(--dispatch-ink); }
|
||||
.dispatch-workspace .editor-grid em, .dispatch-workspace .message-editor em { margin-inline-start: .4rem; color: var(--dispatch-muted); font-size: .75rem; font-weight: 400; }
|
||||
.dispatch-workspace :is(.editor-grid input, .editor-grid select, .message-editor textarea, .dispatch-tags select, .dispatch-filter input, .dispatch-filter select, .dispatch-recipient-tools input, .dispatch-recipient-tools select) { width: 100%; min-height: 2.875rem; border: 1px solid #aabed0; border-radius: .75rem; background: #fff; padding: .65rem .75rem; color: var(--dispatch-ink); font: inherit; font-size: 1rem; box-shadow: none; }
|
||||
.dispatch-workspace select { cursor: pointer; }
|
||||
.dispatch-workspace select:disabled { background: #f2f5f8; color: var(--dispatch-muted); cursor: default; }
|
||||
.dispatch-workspace .editor-grid small, .dispatch-workspace .message-editor small { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; font-weight: 400; }
|
||||
.dispatch-workspace .message-editor { margin: 0 1.25rem 1.25rem; }
|
||||
.dispatch-workspace .message-editor textarea { min-height: 9rem; height: 10rem; resize: vertical; line-height: 1.9; }
|
||||
.dispatch-workspace .dispatch-tags { margin: 0 1.25rem 1.25rem; border: 1px solid var(--dispatch-line); border-radius: .75rem; }
|
||||
.dispatch-workspace summary { min-height: 2.75rem; padding: .65rem .8rem; color: var(--dispatch-ink); font-size: .875rem; font-weight: 700; cursor: pointer; }
|
||||
.dispatch-tags summary span { color: var(--dispatch-muted); font-size: .75rem; font-weight: 400; margin-inline-start: .5rem; }
|
||||
.dispatch-tags label { display: grid; gap: .5rem; padding: 0 .8rem .8rem; font-size: .875rem; }
|
||||
.dispatch-tags small { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .dispatch-tags select { min-height: 5rem; }
|
||||
.dispatch-workspace .dispatch-attachment-picker { margin: 0 1.25rem 1.25rem; padding: 1rem; border-radius: 1rem; background: #f6fbff; }
|
||||
.dispatch-workspace .dispatch-attachment-picker b { color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-attachment-picker b small { display: inline; margin-inline-start: .5rem; }
|
||||
.dispatch-workspace .dispatch-attachment-picker small { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .media-picker-button { display: flex; justify-content: center; align-items: center; min-height: 2.75rem; border: 1px solid #9ebbd1; border-radius: .75rem; padding: .6rem .8rem; background: #fff; color: var(--dispatch-ink); font-size: .875rem; font-weight: 800; cursor: pointer; }
|
||||
.dispatch-workspace .media-picker-button:has(+ input:focus-visible) { outline: 3px solid #1977ce; outline-offset: 3px; }
|
||||
.dispatch-workspace .media-picker-button:focus-visible { outline: 3px solid #1977ce; outline-offset: 3px; }
|
||||
.dispatch-workspace .file-chip { max-width: 100%; box-shadow: none; }
|
||||
.dispatch-workspace .file-chip small { overflow-wrap: anywhere; }
|
||||
.dispatch-workspace .file-chip button { min-width: 2.75rem; min-height: 2.75rem; font-size: 1.25rem; }
|
||||
.dispatch-workspace .dispatch-composer > footer { padding: 1rem 1.25rem; border-radius: 1.25rem; box-shadow: none; }
|
||||
.dispatch-workspace .dispatch-composer footer b { font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-composer footer small { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .dispatch-primary, .dispatch-workspace .dispatch-secondary, .dispatch-workspace .dispatch-composer footer button, .dispatch-workspace .dispatch-filter button, .dispatch-workspace .dispatch-reply-link { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: 2.75rem; border: 1px solid var(--dispatch-ink); border-radius: .75rem; padding: .65rem 1rem; background: var(--dispatch-ink); color: #fff; font: inherit; font-size: .875rem; font-weight: 800; text-decoration: none; cursor: pointer; box-shadow: none; line-height: 1.7; }
|
||||
.dispatch-workspace .dispatch-primary:hover, .dispatch-workspace .dispatch-composer footer button:hover { background: #0b4c8c; transform: none; }
|
||||
.dispatch-workspace .dispatch-secondary { border-color: #aabed0; background: #fff; color: var(--dispatch-ink); }
|
||||
.dispatch-workspace .dispatch-secondary:hover { border-color: var(--dispatch-ink); background: var(--dispatch-soft); transform: none; }
|
||||
.dispatch-workspace button:disabled { cursor: wait; opacity: .65; }
|
||||
.dispatch-compose-guide { border: 1px solid var(--dispatch-line); border-radius: 1.25rem; background: #f8fbfe; padding: 1.25rem; }
|
||||
.dispatch-guide-icon { display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: .875rem; background: #e5f4ff; }
|
||||
.dispatch-compose-guide h2 { margin: .85rem 0 .4rem; font-size: 1.125rem; font-weight: 900; }
|
||||
.dispatch-compose-guide p { font-size: .875rem; line-height: 1.9; color: var(--dispatch-muted); }
|
||||
.dispatch-compose-guide dl { display: grid; gap: 1rem; margin: 1.25rem 0; }
|
||||
.dispatch-compose-guide dt, .dispatch-review-meta dt, .dispatch-operation-details dt { color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-compose-guide dd, .dispatch-review-meta dd, .dispatch-operation-details dd { margin: .25rem 0 0; font-size: .875rem; font-weight: 800; overflow-wrap: anywhere; }
|
||||
.dispatch-compose-guide .dispatch-guide-note { display: flex; align-items: flex-start; gap: .5rem; margin: 0; border-top: 1px solid var(--dispatch-line); padding-top: 1rem; font-size: .75rem; }
|
||||
.dispatch-workspace .dispatch-history { position: static; border-color: var(--dispatch-line); border-radius: 1.25rem; }
|
||||
.dispatch-workspace .dispatch-history > header { gap: 1rem; padding: 1.25rem; }
|
||||
.dispatch-workspace .dispatch-history h2, .dispatch-workspace .stream-head h2 { margin: 0; font-size: 1.125rem; font-weight: 900; }
|
||||
.dispatch-workspace .dispatch-history header p, .dispatch-workspace .stream-head p { color: var(--dispatch-muted); margin: .35rem 0 0; font-size: .875rem; line-height: 1.8; }
|
||||
.dispatch-workspace .dispatch-history header > span { display: block; width: auto; height: auto; flex: none; padding: .3rem .75rem; background: #e5f4ff; font-size: .75rem; border-radius: 1rem; }
|
||||
.dispatch-workspace .dispatch-filter { grid-template-columns: minmax(12rem, 2fr) minmax(10rem, 1fr); align-items: end; gap: 1rem; padding: 1.25rem; background: var(--dispatch-soft); }
|
||||
.dispatch-workspace .dispatch-filter label, .dispatch-workspace .dispatch-recipient-tools label { display: grid; gap: .4rem; font-size: .875rem; font-weight: 700; color: var(--dispatch-ink); }
|
||||
.dispatch-workspace .dispatch-filter > footer { justify-content: flex-start; grid-column: 1 / -1; }
|
||||
.dispatch-workspace .dispatch-filter button { flex: none; }
|
||||
.dispatch-workspace .dispatch-filter footer a { display: inline-flex; align-items: center; min-height: 2.75rem; padding: .5rem; color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-more-filters { grid-column: 1 / -1; }
|
||||
.dispatch-more-filters > div { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1rem; margin-top: .5rem; }
|
||||
.dispatch-workspace .dispatch-results { max-height: none; overflow: visible; }
|
||||
.dispatch-workspace .dispatch-history-card { grid-template-columns: minmax(0, 2fr) auto auto minmax(10rem, 1fr) auto; gap: 1rem; padding: 1.25rem; text-decoration: none; }
|
||||
.dispatch-workspace .dispatch-history-card b { white-space: normal; overflow: visible; font-size: 1rem; color: var(--dispatch-ink); }
|
||||
.dispatch-workspace .dispatch-history-card small, .dispatch-workspace .dispatch-history-card time, .dispatch-history-count { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-history-open { display: flex; align-items: center; gap: .4rem; color: var(--dispatch-ink); font-size: .875rem; font-weight: 800; }
|
||||
.dispatch-workspace .operations-pagination { padding: 1rem 1.25rem; font-size: .875rem; }
|
||||
.dispatch-workspace .operations-pagination a { display: inline-flex; min-height: 2.75rem; align-items: center; padding: .5rem .85rem; color: var(--dispatch-ink); }
|
||||
.dispatch-empty { padding: 2rem 1rem; text-align: center; }
|
||||
.dispatch-empty > svg { width: 2rem; height: 2rem; color: var(--dispatch-muted); }
|
||||
.dispatch-empty h3 { margin: .65rem 0; font-size: 1.125rem; }
|
||||
.dispatch-empty p { color: var(--dispatch-muted); font-size: .875rem; line-height: 1.8; }
|
||||
.dispatch-error-summary { border: 1px solid #dfa5a5; border-radius: .875rem; padding: 1rem; background: #fff6f6; color: #9f1f1f; font-size: .875rem; line-height: 1.9; }
|
||||
.dispatch-error-summary a { color: #9f1f1f; text-decoration: underline; }
|
||||
.dispatch-workspace .errorlist { color: #9f1f1f; font-size: .875rem; line-height: 1.8; }
|
||||
.dispatch-workspace [aria-invalid="true"] { border-color: #9f1f1f; }
|
||||
.dispatch-review-dialog { width: min(42rem, calc(100% - 1.5rem)); max-height: calc(100dvh - 2rem); margin: auto; border: 1px solid var(--dispatch-line); border-radius: 1.25rem; padding: 1.5rem; color: var(--dispatch-ink); background: #fff; overflow-y: auto; box-shadow: 0 1.5rem 5rem #08376b33; }
|
||||
.dispatch-review-dialog::backdrop { background: #08284880; }
|
||||
.dispatch-review-dialog header { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
|
||||
.dispatch-review-dialog h2 { margin: 0; font-size: 1.25rem; font-weight: 900; }
|
||||
.dispatch-workspace .dispatch-dialog-close { display: grid; place-items: center; flex: none; min-width: 2.75rem; height: 2.75rem; border: 1px solid var(--dispatch-line); border-radius: .75rem; background: #fff; color: var(--dispatch-ink); font-size: 1.5rem; padding: 0; box-shadow: none; }
|
||||
.dispatch-review-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1.5rem 0; padding: 1rem; background: var(--dispatch-soft); border-radius: .875rem; }
|
||||
.dispatch-review-dialog h3 { margin: 1rem 0 .5rem; font-size: 1.125rem; }
|
||||
.dispatch-review-body { white-space: pre-wrap; font-size: 1rem; line-height: 1.9; }
|
||||
.dispatch-review-warning { padding: 1rem; border: 1px solid #efd8ad; border-radius: .75rem; background: #fff8eb; color: #805300; font-size: .875rem; line-height: 1.9; }
|
||||
.dispatch-inquiry-recommendation { padding: 1rem; border: 1px solid #f2b5bb; border-inline-start: 4px solid #b42332; border-radius: .75rem; background: #fff2f3; color: #a11727; font-size: .875rem; line-height: 1.9; }
|
||||
.dispatch-inquiry-recommendation p { margin: .5rem 0 0; }
|
||||
.dispatch-review-dialog footer { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .75rem; margin-top: 1.25rem; }
|
||||
.dispatch-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; font-size: .75rem; color: var(--dispatch-muted); }
|
||||
.dispatch-breadcrumb a { display: inline-flex; align-items: center; gap: .4rem; min-height: 2.75rem; color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-report-hero { align-items: center; border: 0; border-radius: 0; padding: 0; background: transparent; box-shadow: none; }
|
||||
.dispatch-workspace .dispatch-report-title { min-width: 0; }
|
||||
.dispatch-workspace .dispatch-report-title h1 { color: var(--dispatch-ink); font-size: 1.75rem; line-height: 1.6; font-weight: 900; }
|
||||
.dispatch-workspace .dispatch-title-line { flex-wrap: wrap; }
|
||||
.dispatch-workspace .report-status { padding: .35rem .7rem; font-size: .75rem; font-weight: 800; background: #eaf0f5; color: #405d75; }
|
||||
.dispatch-workspace .report-status.status-sent { background: #e2f5ea; color: #166347; }
|
||||
.dispatch-workspace .report-status.status-partial { background: #fff0e1; color: #805300; }
|
||||
.dispatch-workspace .dispatch-meta-list span { border: 0; background: transparent; padding: 0; color: var(--dispatch-muted); font-size: .75rem; flex-wrap: wrap; }
|
||||
.dispatch-workspace .dispatch-meta-list span + span { border-inline-start: 1px solid #c6d4e0; padding-inline-start: .75rem; }
|
||||
.dispatch-workspace .dispatch-kpi-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .75rem; overflow: visible; }
|
||||
.dispatch-workspace .dispatch-kpi { min-width: 0; align-items: flex-start; gap: .5rem; border-radius: 1rem; padding: 1rem; box-shadow: none; }
|
||||
.dispatch-workspace .dispatch-kpi > svg { color: var(--dispatch-ink); margin-top: .25rem; }
|
||||
.dispatch-workspace .dispatch-kpi small { color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-kpi strong { color: var(--dispatch-ink); font-size: 1.5rem; font-weight: 900; }
|
||||
.dispatch-workspace .dispatch-kpi p { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .delivery-overview { border-color: var(--dispatch-line); border-radius: 1rem; padding: 1rem 1.25rem; }
|
||||
.dispatch-workspace .delivery-progress-copy { flex-wrap: wrap; }
|
||||
.dispatch-workspace .delivery-progress-copy strong { color: var(--dispatch-ink); font-size: 1rem; }
|
||||
.dispatch-workspace .delivery-progress-copy p, .dispatch-workspace .delivery-overview-note span { color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-workspace .delivery-progress-copy span, .dispatch-workspace .delivery-overview-note b { font-size: .875rem; color: var(--dispatch-ink); }
|
||||
.dispatch-workspace .delivery-progress-track { height: .375rem; background: #e7edf2; box-shadow: none; }
|
||||
.dispatch-workspace .delivery-progress-track span { background: #16815c; }
|
||||
.dispatch-workspace .dispatch-original-message { gap: .85rem; padding: 1.25rem; border-color: var(--dispatch-line); border-radius: 1.25rem; background: #fff; box-shadow: none; }
|
||||
.dispatch-workspace .dispatch-original-message h2 { color: var(--dispatch-ink); font-size: 1.125rem; }
|
||||
.dispatch-workspace .dispatch-original-message header > span { direction: rtl; color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-workspace .dispatch-original-message blockquote { border-inline-start: 3px solid #1977ce; border-right: 0; background: var(--dispatch-soft); color: var(--dispatch-ink); font-size: 1rem; line-height: 1.9; padding: .75rem 1rem; overflow-wrap: anywhere; }
|
||||
.dispatch-operation-details { border-top: 1px solid var(--dispatch-line); }
|
||||
.dispatch-operation-details dl { display: flex; flex-wrap: wrap; gap: 1rem 2rem; padding: 0 .8rem; margin: .4rem 0; }
|
||||
.dispatch-workspace .dispatch-recipient-report { border: 1px solid var(--dispatch-line); border-radius: 1.25rem; background: #fff; overflow: hidden; }
|
||||
.dispatch-workspace .stream-head { align-items: flex-start; gap: 1rem; padding: 1.25rem; background: #fff; }
|
||||
.dispatch-workspace .stream-head > span { flex: none; color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-recipient-tools { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) auto; gap: .75rem; align-items: end; border-block: 1px solid var(--dispatch-line); padding: 1rem 1.25rem; background: var(--dispatch-soft); }
|
||||
.dispatch-recipient-tools > p { grid-column: 1 / -1; margin: 0; color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-workspace .table-scroll { overflow: visible; }
|
||||
.dispatch-workspace .dispatch-detail-table { width: 100%; min-width: 0; table-layout: fixed; font-size: .875rem; }
|
||||
.dispatch-workspace .dispatch-detail-table th { padding: .8rem 1rem; color: var(--dispatch-muted); font-size: .75rem; background: var(--dispatch-soft); text-align: right; }
|
||||
.dispatch-detail-table th:nth-child(1) { width: 20%; }
|
||||
.dispatch-detail-table th:nth-child(2) { width: 26%; }
|
||||
.dispatch-detail-table th:nth-child(3) { width: 14%; }
|
||||
.dispatch-detail-table th:nth-child(4) { width: 40%; }
|
||||
.dispatch-workspace .dispatch-detail-table td { padding: 1rem; min-width: 0; overflow-wrap: anywhere; }
|
||||
.dispatch-workspace .recipient-cell { min-width: 0; }
|
||||
.dispatch-workspace .recipient-cell strong, .dispatch-workspace .ticket-reference strong, .dispatch-workspace .sms-state-card strong, .dispatch-workspace .engagement-state strong { color: var(--dispatch-ink); font-size: .875rem; }
|
||||
.dispatch-workspace .recipient-cell small, .dispatch-workspace .sms-state-card p, .dispatch-workspace .sms-state-card small, .dispatch-workspace .engagement-state small { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .ticket-reference { min-height: 2.75rem; align-content: center; margin-top: .25rem; }
|
||||
.dispatch-workspace .ticket-reference strong { white-space: normal; overflow-wrap: anywhere; font-weight: 800; }
|
||||
.dispatch-workspace .ticket-state-pill { color: var(--dispatch-ink); font-size: .75rem; white-space: normal; }
|
||||
.dispatch-workspace .dispatch-sms-state { min-width: 0; }
|
||||
.dispatch-workspace .sms-state-card { padding: .75rem; }
|
||||
.dispatch-workspace .sms-state-card > div { min-width: 0; }
|
||||
.dispatch-workspace .sms-state-icon { width: 1.5rem; height: 1.5rem; background: transparent; }
|
||||
.dispatch-workspace .sms-technical-details, .dispatch-workspace .sms-error-panel { font-size: .875rem; }
|
||||
.dispatch-workspace .sms-technical-details dt { color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-workspace .sms-technical-details dd { font-size: .875rem; }
|
||||
.dispatch-workspace .inline-retry-form button { min-height: 2.75rem; border-radius: .75rem; padding: .5rem; color: #9f1f1f; font-size: .875rem; }
|
||||
.dispatch-workspace .engagement-state { min-width: 0; gap: .5rem; }
|
||||
.dispatch-workspace .engagement-state > svg { color: #526c86; }
|
||||
.dispatch-workspace .engagement-state.has-engagement > svg { color: #5c369d; }
|
||||
.dispatch-workspace .recipient-reply { min-width: 0; margin-top: .75rem; padding: .875rem; border: 1px solid var(--dispatch-line); border-radius: .75rem; background: #f6fbff; }
|
||||
.dispatch-workspace .recipient-reply p { color: var(--dispatch-ink); font-size: .875rem; line-height: 1.9; overflow-wrap: anywhere; }
|
||||
.dispatch-workspace .recipient-reply time { color: var(--dispatch-muted); font-size: .75rem; }
|
||||
.dispatch-response-files { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
|
||||
.dispatch-response-files a { font-size: .8rem; overflow-wrap: anywhere; text-decoration: underline; }
|
||||
.dispatch-workspace .recipient-reply small, .dispatch-workspace .no-reply-state { color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-workspace .no-reply-state { margin: 0; }
|
||||
.dispatch-workspace .dispatch-reply-link { margin-top: .75rem; width: 2.25rem; min-height: 2.25rem; padding: .4rem; border-color: var(--dispatch-line); background: #f6fbff; color: var(--dispatch-ink); }
|
||||
.dispatch-management { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: 1.25rem; border: 1px solid var(--dispatch-line); border-radius: 1.25rem; padding: 1.25rem; background: #fff; }
|
||||
.dispatch-management h2 { margin: 0; font-size: 1.125rem; font-weight: 900; }
|
||||
.dispatch-management p { margin: .4rem 0 0; color: var(--dispatch-muted); font-size: .875rem; line-height: 1.9; }
|
||||
.dispatch-management-actions { display: grid; gap: .75rem; }
|
||||
.dispatch-management form { margin: 0; }
|
||||
.dispatch-management button { width: 100%; }
|
||||
.dispatch-management small { display: block; margin-top: .4rem; color: var(--dispatch-muted); font-size: .75rem; line-height: 1.8; }
|
||||
.dispatch-management .dispatch-complete { display: flex; align-items: flex-start; gap: .5rem; margin: 0; color: #166347; }
|
||||
.dispatch-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
|
||||
@media (max-width: 1200px) {
|
||||
.dispatch-workspace .dispatch-history-card { grid-template-columns: minmax(0, 1fr) auto; gap: .6rem 1rem; }
|
||||
.dispatch-history-main { grid-column: 1; }
|
||||
.dispatch-history-card time { grid-column: 1; }
|
||||
.dispatch-workspace .dispatch-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||
.dispatch-workspace .dispatch-detail-table thead { display: none; }
|
||||
.dispatch-workspace .dispatch-detail-table, .dispatch-workspace .dispatch-detail-table tbody { display: block; }
|
||||
.dispatch-workspace .dispatch-detail-table tr { display: grid; grid-template-columns: 1fr 1fr; border-bottom: .5rem solid var(--dispatch-soft); }
|
||||
.dispatch-workspace .dispatch-detail-table td { display: block; width: auto; border-bottom: 1px solid var(--dispatch-line); }
|
||||
.dispatch-workspace .dispatch-detail-table td::before { display: block; margin-bottom: .6rem; content: attr(data-label); color: var(--dispatch-muted); font-size: .75rem; font-weight: 700; }
|
||||
}
|
||||
@media (max-width: 1000px) {
|
||||
.dispatch-compose-layout { grid-template-columns: minmax(0, 1fr); }
|
||||
.dispatch-compose-guide { padding: 1rem; }
|
||||
.dispatch-compose-guide dl { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||
.dispatch-more-filters > div { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.dispatch-workspace { gap: 1rem; }
|
||||
.dispatch-page-heading { align-items: stretch; flex-direction: column; gap: .75rem; }
|
||||
.dispatch-page-heading h1, .dispatch-workspace .dispatch-report-title h1 { font-size: 1.5rem; }
|
||||
.dispatch-privacy { max-width: none; }
|
||||
.dispatch-summary-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0; }
|
||||
.dispatch-summary-strip > div { min-height: 4rem; padding: .75rem; }
|
||||
.dispatch-summary-strip > div:nth-child(3) { border-inline-start: 0; }
|
||||
.dispatch-summary-strip > div:nth-child(n+3) { border-top: 1px solid var(--dispatch-line); }
|
||||
.dispatch-view-switch a { flex: 1; justify-content: center; padding-inline: .5rem; }
|
||||
.dispatch-workspace .dispatch-composer > section > header, .dispatch-workspace .editor-grid { padding: 1rem; }
|
||||
.dispatch-workspace .editor-grid { grid-template-columns: minmax(0, 1fr); }
|
||||
.dispatch-workspace .message-editor, .dispatch-workspace .dispatch-tags, .dispatch-workspace .dispatch-attachment-picker { margin-inline: 1rem; }
|
||||
.dispatch-workspace .dispatch-composer > footer { align-items: stretch; flex-direction: column; gap: .75rem; padding: 1rem; }
|
||||
.dispatch-workspace .dispatch-composer footer button { width: 100%; }
|
||||
.dispatch-compose-guide dl { grid-template-columns: 1fr; }
|
||||
.dispatch-workspace .dispatch-filter { grid-template-columns: minmax(0, 1fr); padding: 1rem; }
|
||||
.dispatch-workspace .dispatch-history > header { flex-wrap: wrap; padding: 1rem; }
|
||||
.dispatch-workspace .dispatch-history-card { padding: 1rem; }
|
||||
.dispatch-more-filters > div { grid-template-columns: minmax(0, 1fr); }
|
||||
.dispatch-review-dialog { padding: 1rem; }
|
||||
.dispatch-review-dialog footer { flex-direction: column-reverse; }
|
||||
.dispatch-review-meta { grid-template-columns: minmax(0, 1fr); }
|
||||
.dispatch-workspace .dispatch-report-hero { display: grid; }
|
||||
.dispatch-workspace .dispatch-meta-list span + span { border: 0; padding: 0; }
|
||||
.dispatch-workspace .dispatch-meta-list { display: grid; gap: .4rem; }
|
||||
.dispatch-workspace .dispatch-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||
.dispatch-workspace .dispatch-kpi { padding: .85rem; }
|
||||
.dispatch-workspace .dispatch-kpi > svg { display: none; }
|
||||
.dispatch-workspace .dispatch-original-message { padding: 1rem; }
|
||||
.dispatch-workspace .dispatch-original-message header { display: grid; gap: .5rem; }
|
||||
.dispatch-workspace .stream-head { flex-wrap: wrap; padding: 1rem; }
|
||||
.dispatch-recipient-tools { grid-template-columns: minmax(0, 1fr); padding: 1rem; }
|
||||
.dispatch-workspace .dispatch-detail-table tr { grid-template-columns: minmax(0, 1fr); }
|
||||
.dispatch-workspace .dispatch-detail-table td { padding: 1rem; }
|
||||
.dispatch-management { grid-template-columns: minmax(0, 1fr); padding: 1rem; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.dispatch-workspace *, .dispatch-workspace *::before, .dispatch-workspace *::after { transition: none; animation: none; scroll-behavior: auto; }
|
||||
}
|
||||
@@ -9,3 +9,13 @@
|
||||
.customer-receipt-form #selected-payment .pay-deposit-warning{margin-top:12px;color:#9f1f1f;font-size:14px}.customer-receipt-form #id_deposit_id.pay-deposit-emphasis{color:#9f1f1f;border-color:#d39090;font-weight:700}
|
||||
.pay-link-message{max-width:620px;margin:48px auto}.pay-link-message .pay-card{padding:32px;border-radius:23px}.pay-link-message h1{margin:20px 0 12px;font-size:24px}.pay-link-message p{color:#526c86;font-size:16px;line-height:1.9;margin-bottom:24px}.pay-link-message .pay-actions{gap:12px;flex-wrap:wrap}
|
||||
@media(max-width:639px){.pay-link-message{margin:24px auto}.pay-link-message .pay-card{padding:24px 18px}.pay-link-status{padding:12px 14px;margin-bottom:18px}.pay-link-session-label{display:none}.pay-link-message .pay-button{width:100%}}
|
||||
|
||||
/* Receipt action is emphasized only on the customer's individual notice page. */
|
||||
.customer-notice-detail .pay-receipt-guidance{margin:0 0 20px;font-size:14px;line-height:1.8;color:inherit}
|
||||
.customer-notice-detail .pay-receipt-next-step{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-block:20px;padding:18px 20px;border:1px solid #cde6f7;border-radius:16px;background:#f6fbff}
|
||||
.customer-notice-detail .pay-receipt-next-step>div{min-width:0}
|
||||
.customer-notice-detail .pay-receipt-next-step h2{margin:0 0 4px;font-size:18px;font-weight:800}
|
||||
.customer-notice-detail .pay-receipt-next-step p{margin:0;color:#526c86;font-size:14px;line-height:1.8}
|
||||
.customer-notice-detail .pay-receipt-action{gap:10px;min-height:52px;padding:12px 20px;font-size:16px;flex-shrink:0}
|
||||
.customer-notice-detail .pay-receipt-action .cs-icon{width:22px;height:22px}
|
||||
@media(max-width:639px){.customer-notice-detail .pay-receipt-next-step{flex-direction:column;align-items:stretch;gap:16px;padding:16px}.customer-notice-detail .pay-receipt-action{width:100%}}
|
||||
@@ -0,0 +1,254 @@
|
||||
/* Progressive enhancement: native forms and private-ticket links work without this script. */
|
||||
(() => {
|
||||
'use strict';
|
||||
const number = new Intl.NumberFormat('fa-IR');
|
||||
const displayCount = count => `${number.format(count)} نفر`;
|
||||
|
||||
function initSections(root) {
|
||||
const tabs = Array.from(root.querySelectorAll('[data-dispatch-tab]'));
|
||||
const panels = Array.from(root.querySelectorAll('[data-dispatch-panel]'));
|
||||
const hasErrors = Boolean(root.querySelector('.dispatch-error-summary'));
|
||||
const filters = new URLSearchParams(location.search);
|
||||
const hasFilters = ['q', 'status', 'unit', 'group', 'created_from', 'created_to', 'page'].some(key => filters.get(key));
|
||||
const selectedSection = () => {
|
||||
if (hasErrors) return 'compose';
|
||||
if (location.hash === '#dispatch-history-panel') return 'history';
|
||||
if (location.hash === '#dispatch-compose-panel') return 'compose';
|
||||
return hasFilters ? 'history' : 'compose';
|
||||
};
|
||||
const show = section => {
|
||||
tabs.forEach(tab => {
|
||||
const active = tab.dataset.dispatchTab === section;
|
||||
tab.setAttribute('aria-selected', String(active));
|
||||
tab.setAttribute('aria-current', String(active));
|
||||
tab.tabIndex = active ? 0 : -1;
|
||||
});
|
||||
panels.forEach(panel => { panel.hidden = panel.dataset.dispatchPanel !== section; });
|
||||
};
|
||||
root.querySelector('.dispatch-view-switch').setAttribute('role', 'tablist');
|
||||
tabs.forEach((tab, index) => {
|
||||
tab.setAttribute('role', 'tab');
|
||||
tab.setAttribute('aria-controls', `dispatch-${tab.dataset.dispatchTab}-panel`);
|
||||
tab.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
history.pushState(null, '', tab.getAttribute('href'));
|
||||
show(tab.dataset.dispatchTab);
|
||||
});
|
||||
tab.addEventListener('keydown', event => {
|
||||
let next;
|
||||
if (event.key === 'ArrowLeft') next = (index + 1) % tabs.length;
|
||||
if (event.key === 'ArrowRight') next = (index + tabs.length - 1) % tabs.length;
|
||||
if (event.key === 'Home') next = 0;
|
||||
if (event.key === 'End') next = tabs.length - 1;
|
||||
if (next === undefined) return;
|
||||
event.preventDefault();
|
||||
tabs[next].click();
|
||||
tabs[next].focus();
|
||||
});
|
||||
});
|
||||
panels.forEach(panel => panel.setAttribute('role', 'tabpanel'));
|
||||
window.addEventListener('popstate', () => show(selectedSection()));
|
||||
show(selectedSection());
|
||||
}
|
||||
|
||||
function fillOptions(select, items, labelKey, placeholder, autoSelect = false) {
|
||||
const previous = select.value;
|
||||
select.replaceChildren(new Option(placeholder, ''));
|
||||
items.forEach(item => select.add(new Option(item[labelKey], String(item.id))));
|
||||
if (items.some(item => String(item.id) === previous)) select.value = previous;
|
||||
else if (autoSelect && items.length === 1) select.value = String(items[0].id);
|
||||
}
|
||||
|
||||
function initRecipients(root, form, data) {
|
||||
const operation = form.elements.operation_type;
|
||||
const unit = form.elements.unit;
|
||||
const group = form.elements.contact_group;
|
||||
const category = form.elements.category;
|
||||
const groupHint = root.querySelector('[data-dispatch-group-hint]');
|
||||
const text = (selector, value) => { root.querySelector(selector).textContent = value; };
|
||||
const updateSummary = () => {
|
||||
const selected = data.groups.find(item => String(item.id) === group.value);
|
||||
updateResponseOptions(root, form, selected);
|
||||
text('[data-dispatch-unit-summary]', unit.value ? unit.selectedOptions[0].textContent : 'انتخاب نشده');
|
||||
text('[data-dispatch-group-summary]', selected ? selected.name : 'انتخاب نشده');
|
||||
text('[data-dispatch-count-summary]', selected ? displayCount(selected.recipient_count) : 'پس از انتخاب گروه');
|
||||
group.setCustomValidity(selected && !selected.recipient_count ? 'این گروه مخاطب فعال دارای شماره همراه ندارد؛ گروه دیگری انتخاب کنید.' : '');
|
||||
groupHint.textContent = selected ? `${displayCount(selected.recipient_count)} فعال دارای شماره همراه؛ تعداد نهایی هنگام ثبت بررسی میشود.` : 'فقط گروههای واحد انتخابشده نمایش داده میشوند.';
|
||||
};
|
||||
const updateGroupOptions = () => {
|
||||
const hasUnit = Boolean(unit.value);
|
||||
const groups = data.groups.filter(item => String(item.unit_id) === unit.value);
|
||||
const categories = data.categories.filter(item => String(item.unit_id) === unit.value);
|
||||
const applicableCategories = categories.length ? categories : data.categories.filter(item => item.unit_id === null);
|
||||
fillOptions(group, hasUnit ? groups : [], 'name', hasUnit ? 'گروه مخاطبان را انتخاب کنید' : 'ابتدا واحد را انتخاب کنید');
|
||||
fillOptions(category, hasUnit ? applicableCategories : [], 'title', hasUnit ? 'دستهبندی را انتخاب کنید' : 'ابتدا واحد را انتخاب کنید');
|
||||
group.disabled = !hasUnit;
|
||||
category.disabled = !hasUnit;
|
||||
updateSummary();
|
||||
};
|
||||
const updateUnitOptions = () => {
|
||||
const units = data.units.filter(item => item.operations.includes(operation.value));
|
||||
fillOptions(unit, units, 'name', 'واحد ارسالکننده را انتخاب کنید', !root.querySelector('.dispatch-error-summary'));
|
||||
updateGroupOptions();
|
||||
};
|
||||
operation.addEventListener('change', updateUnitOptions);
|
||||
unit.addEventListener('change', updateGroupOptions);
|
||||
group.addEventListener('change', updateSummary);
|
||||
updateUnitOptions();
|
||||
return () => data.groups.find(item => String(item.id) === group.value);
|
||||
}
|
||||
|
||||
function updateResponseOptions(root, form, group) {
|
||||
const sms = form.elements.notify_opening_sms;
|
||||
const individual = form.elements.response_mode.value === 'INDIVIDUAL';
|
||||
const oversized = Boolean(group && group.recipient_count > 15);
|
||||
if (sms.dataset.openingPreference === undefined) sms.dataset.openingPreference = String(sms.checked);
|
||||
sms.disabled = individual || oversized;
|
||||
sms.checked = !sms.disabled && sms.dataset.openingPreference === 'true';
|
||||
root.querySelector('[data-opening-sms-hint]').textContent = individual
|
||||
? 'پیامک بازگشایی فقط در حالت یکجا مجاز است.'
|
||||
: oversized ? 'بیش از ۱۵ گیرندهٔ واجد شرایط؛ اطلاعرسانی بازگشایی با پیامک مجاز نیست.'
|
||||
: 'پس از بازگشایی فقط پاسخدهندگان پیامک دریافت میکنند؛ حداکثر ۱۵ گیرنده مجاز است.';
|
||||
}
|
||||
|
||||
function initReview(root, form, selectedGroup) {
|
||||
const dialog = root.querySelector('[data-dispatch-review]');
|
||||
if (typeof dialog.showModal !== 'function') return;
|
||||
const send = form.querySelector('[data-dispatch-send]');
|
||||
const confirm = dialog.querySelector('[data-dispatch-confirm]');
|
||||
let confirmed = false;
|
||||
send.textContent = 'بررسی و ادامه';
|
||||
const setText = (selector, value) => { dialog.querySelector(selector).textContent = value; };
|
||||
const review = () => {
|
||||
const group = selectedGroup();
|
||||
if (!form.reportValidity() || !group) return;
|
||||
// The shared uploader empties picker inputs only after image preparation completes.
|
||||
if (Array.from(form.querySelectorAll('[data-gallery-input], [data-document-input]')).some(input => input.files.length)) {
|
||||
root.querySelector('[data-compression-status]').textContent = 'آمادهسازی پیوستها ادامه دارد؛ پس از پایان دوباره بررسی و ادامه را بزنید.';
|
||||
return;
|
||||
}
|
||||
setText('[data-review-unit]', form.elements.unit.selectedOptions[0].textContent);
|
||||
setText('[data-review-group]', group.name);
|
||||
setText('[data-review-count]', displayCount(group.recipient_count));
|
||||
setText('[data-review-response-policy]', `${form.elements.response_mode.value === 'SEALED' ? 'بازگشایی یکجا' : 'مشاهده جداگانه'}؛ پیامک بازگشایی: ${form.elements.notify_opening_sms.checked && !form.elements.notify_opening_sms.disabled ? 'فعال' : 'غیرفعال'}`);
|
||||
dialog.querySelector('[data-review-inquiry-recommendation]').hidden = form.elements.response_mode.value === 'SEALED' && form.elements.notify_opening_sms.checked && !form.elements.notify_opening_sms.disabled;
|
||||
dialog.querySelector('[data-review-inquiry-limit]').hidden = group.recipient_count <= 15;
|
||||
const files = Array.from(form.elements.files.files);
|
||||
setText('[data-review-files]', files.length ? files.map(file => file.name).join('، ') : 'بدون پیوست');
|
||||
setText('[data-review-subject]', form.elements.subject.value);
|
||||
setText('[data-review-body]', form.elements.body.value);
|
||||
dialog.showModal();
|
||||
dialog.querySelector('[data-dispatch-review-close]').focus();
|
||||
};
|
||||
// Capture before shared uploader/UI listeners: reviewing must not disable submission controls.
|
||||
form.addEventListener('submit', event => {
|
||||
if (confirmed) return;
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
review();
|
||||
}, true);
|
||||
dialog.querySelectorAll('[data-dispatch-review-close]').forEach(button => button.addEventListener('click', () => dialog.close()));
|
||||
dialog.addEventListener('close', () => { if (!confirmed) send.focus(); });
|
||||
confirm.addEventListener('click', () => {
|
||||
if (confirmed || !form.reportValidity()) return;
|
||||
confirmed = true;
|
||||
confirm.disabled = true;
|
||||
confirm.textContent = 'در حال ثبت…';
|
||||
dialog.close();
|
||||
form.requestSubmit(send);
|
||||
});
|
||||
}
|
||||
|
||||
function initErrors(root, form) {
|
||||
form.querySelectorAll('.errorlist').forEach((list, index) => {
|
||||
const control = list.parentElement.querySelector('input, select, textarea');
|
||||
if (!control) return;
|
||||
list.id = `dispatch-error-${index}`;
|
||||
control.setAttribute('aria-invalid', 'true');
|
||||
control.setAttribute('aria-describedby', list.id);
|
||||
});
|
||||
const summary = root.querySelector('.dispatch-error-summary');
|
||||
if (!summary) return;
|
||||
summary.querySelectorAll('a').forEach(link => link.addEventListener('click', event => {
|
||||
const control = document.getElementById(link.hash.slice(1));
|
||||
if (!control) return;
|
||||
event.preventDefault();
|
||||
const disclosure = control.closest('details');
|
||||
if (disclosure) disclosure.open = true;
|
||||
control.focus();
|
||||
}));
|
||||
summary.focus();
|
||||
}
|
||||
|
||||
function initComposer(root) {
|
||||
const form = root.querySelector('#dispatch-compose-form');
|
||||
const data = JSON.parse(root.querySelector('#dispatch-options').textContent);
|
||||
initSections(root);
|
||||
const selectedGroup = initRecipients(root, form, data);
|
||||
form.elements.notify_opening_sms.addEventListener('change', event => {
|
||||
event.target.dataset.openingPreference = String(event.target.checked);
|
||||
});
|
||||
form.querySelectorAll('[name="response_mode"]').forEach(input => input.addEventListener('change', () => updateResponseOptions(root, form, selectedGroup())));
|
||||
initReview(root, form, selectedGroup);
|
||||
initErrors(root, form);
|
||||
// Visible, keyboard-operable file labels retain the shared uploader's original inputs.
|
||||
root.querySelectorAll('.media-picker-button').forEach(label => {
|
||||
label.tabIndex = 0;
|
||||
label.setAttribute('role', 'button');
|
||||
label.addEventListener('keydown', event => {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') return;
|
||||
event.preventDefault();
|
||||
document.getElementById(label.htmlFor).click();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function normalizeSearch(value) {
|
||||
return value.toLowerCase().replace(/[يى]/g, 'ی').replace(/ك/g, 'ک')
|
||||
.replace(/[۰-۹]/g, digit => String(digit.charCodeAt(0) - 1776))
|
||||
.replace(/[٠-٩]/g, digit => String(digit.charCodeAt(0) - 1632))
|
||||
.replace(/[\s\u200c-]+/g, '');
|
||||
}
|
||||
|
||||
function initReport(root) {
|
||||
const rows = Array.from(root.querySelectorAll('[data-recipient-row]'));
|
||||
if (!rows.length) return;
|
||||
const tools = root.querySelector('[data-recipient-tools]');
|
||||
const search = tools.querySelector('[data-recipient-search]');
|
||||
const filter = tools.querySelector('[data-recipient-filter]');
|
||||
const status = tools.querySelector('[data-recipient-result-count]');
|
||||
const empty = root.querySelector('[data-recipient-empty]');
|
||||
const matches = {
|
||||
all: () => true,
|
||||
answered: row => row.dataset.answered === 'true',
|
||||
unanswered: row => row.dataset.answered === 'false',
|
||||
opened: row => row.dataset.opened === 'true',
|
||||
unopened: row => row.dataset.opened === 'false',
|
||||
retryable: row => row.dataset.retryable === 'true',
|
||||
active: row => row.dataset.active === 'true',
|
||||
};
|
||||
const update = () => {
|
||||
const query = normalizeSearch(search.value);
|
||||
let visible = 0;
|
||||
rows.forEach(row => {
|
||||
row.hidden = !normalizeSearch(row.dataset.search).includes(query) || !matches[filter.value](row);
|
||||
if (!row.hidden) visible += 1;
|
||||
});
|
||||
status.textContent = `${number.format(visible)} از ${number.format(rows.length)} مخاطب`;
|
||||
empty.hidden = visible > 0;
|
||||
};
|
||||
search.addEventListener('input', update);
|
||||
filter.addEventListener('change', update);
|
||||
root.querySelectorAll('[data-recipient-reset]').forEach(button => button.addEventListener('click', () => {
|
||||
search.value = '';
|
||||
filter.value = 'all';
|
||||
update();
|
||||
search.focus();
|
||||
}));
|
||||
tools.hidden = false;
|
||||
update();
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-dispatch-workspace]').forEach(initComposer);
|
||||
document.querySelectorAll('[data-dispatch-report]').forEach(initReport);
|
||||
})();
|
||||
Reference in new issue
Block a user