489 lines
10 KiB
SCSS
489 lines
10 KiB
SCSS
/**
|
|
* Copyright since 2025 Mifos Initiative
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
$primary: #0f766e;
|
|
|
|
.dte-container {
|
|
// Wider than a normal form page: a collection row carries six fields side by side, and a clerk
|
|
// keying a round should see the whole of it.
|
|
max-width: 1280px;
|
|
margin: 0 auto;
|
|
padding: 20px 16px;
|
|
}
|
|
|
|
.dte-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
margin-bottom: 20px;
|
|
|
|
&__title {
|
|
margin: 0;
|
|
font-size: 22px;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.dte-back {
|
|
color: $primary;
|
|
}
|
|
|
|
.dte-card {
|
|
background: var(--md-sys-color-surface, #fff);
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgb(0 0 0 / 8%);
|
|
padding: 20px 24px 24px;
|
|
}
|
|
|
|
.dte-info-panels {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 16px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.dte-info-panel {
|
|
border: 1px solid rgb(0 0 0 / 10%);
|
|
border-radius: 8px;
|
|
padding: 12px 16px;
|
|
background: rgb(15 118 110 / 4%);
|
|
|
|
&__title {
|
|
font-weight: 600;
|
|
font-size: 13px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
color: $primary;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
&__hint {
|
|
margin: 0;
|
|
color: rgb(0 0 0 / 50%);
|
|
font-size: 13px;
|
|
}
|
|
|
|
dl {
|
|
display: grid;
|
|
grid-template-columns: auto 1fr;
|
|
gap: 4px 12px;
|
|
margin: 0;
|
|
}
|
|
|
|
dt {
|
|
font-weight: 500;
|
|
color: rgb(0 0 0 / 60%);
|
|
font-size: 13px;
|
|
}
|
|
|
|
dd {
|
|
margin: 0;
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
.dte-controls {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 12px;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
// A sensible floor for the fields laid out with flex in .dte-controls, where there is room to spare.
|
|
.dte-field {
|
|
min-width: 180px;
|
|
|
|
&--wide {
|
|
grid-column: span 2;
|
|
}
|
|
}
|
|
|
|
// Inside the collection grid the track decides the width, not the field. Left to its own 180px
|
|
// floor a field refuses to shrink into a narrower track and overruns the one beside it.
|
|
.dte-collection-row .dte-field {
|
|
width: 100%;
|
|
min-width: 0;
|
|
}
|
|
|
|
.dte-section {
|
|
padding: 16px 0;
|
|
border-top: 1px solid rgb(0 0 0 / 8%);
|
|
// A very narrow window scrolls the grid sideways rather than the whole page.
|
|
overflow-x: auto;
|
|
|
|
&__header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
margin-bottom: 16px;
|
|
|
|
i {
|
|
color: $primary;
|
|
}
|
|
|
|
h3 {
|
|
margin: 0;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
flex: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
.dte-add-row {
|
|
color: $primary;
|
|
}
|
|
|
|
.dte-empty {
|
|
color: rgb(0 0 0 / 50%);
|
|
font-size: 14px;
|
|
margin: 0;
|
|
}
|
|
|
|
.dte-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 8px 16px;
|
|
}
|
|
|
|
/*
|
|
* One collection per row. Fixed columns rather than an even split, so the row holds its shape as
|
|
* fields come and go - Cheque No and Token No only appear for a non-cash entry - and the party
|
|
* picker gets the width its "code · name · daily amount" needs.
|
|
*/
|
|
.dte-collection-row {
|
|
display: grid;
|
|
grid-template-columns:
|
|
minmax(0, 2.2fr) /* Party */
|
|
minmax(0, 1fr) /* TRTP */
|
|
minmax(0, 1fr) /* AC Type */
|
|
minmax(0, 1.4fr) /* A/C No. */
|
|
minmax(0, 1fr) /* Amount */
|
|
minmax(0, 1.6fr) /* Description */
|
|
auto; /* remove */
|
|
|
|
gap: 8px 12px;
|
|
align-items: start;
|
|
padding: 10px 0;
|
|
border-top: 1px dashed rgb(0 0 0 / 10%);
|
|
|
|
&:first-of-type {
|
|
border-top: none;
|
|
}
|
|
|
|
// Cheque No and Token No push Description and the remove button onto a second line, which is
|
|
// what a non-cash entry should look like rather than a row running off the screen.
|
|
&:has(.dte-field--instrument) {
|
|
grid-template-columns:
|
|
minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr)
|
|
minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.6fr) auto;
|
|
}
|
|
}
|
|
|
|
.dte-collection-row .dte-field--wide {
|
|
grid-column: span 2;
|
|
}
|
|
|
|
@media (width <= 1200px) {
|
|
.dte-collection-row,
|
|
.dte-collection-row:has(.dte-field--instrument) {
|
|
grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
|
|
}
|
|
}
|
|
|
|
.dte-remove-row {
|
|
color: #b91c1c;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.dte-action-bar {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 12px;
|
|
margin-top: 20px;
|
|
padding-top: 16px;
|
|
border-top: 1px solid rgb(0 0 0 / 8%);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
@media (width <= 1000px) {
|
|
.dte-info-panels {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.dte-grid {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.dte-collection-row {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
}
|
|
|
|
/* Resolved name under an Agent / Party Code field — the check that the right record was found. */
|
|
.dte-hint--found {
|
|
color: #15803d;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.dte-hint--missing {
|
|
color: #b91c1c;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Marks an agent in the list who is no longer collecting - only offered for settlement. */
|
|
.dte-agent-off {
|
|
color: #b45309;
|
|
font-size: 12px;
|
|
font-style: italic;
|
|
margin-left: 6px;
|
|
}
|
|
|
|
/* The figure the clerk actually verifies against the passbook before saving. */
|
|
.dte-after {
|
|
font-weight: 600;
|
|
color: #0f766e;
|
|
}
|
|
|
|
/* What the agent should be handing over for this round. */
|
|
.dte-total {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
align-items: baseline;
|
|
gap: 14px;
|
|
padding: 10px 4px 2px;
|
|
border-top: 1px solid rgb(0 0 0 / 10%);
|
|
font-size: 0.88rem;
|
|
color: rgb(0 0 0 / 60%);
|
|
|
|
strong {
|
|
font-size: 1.1rem;
|
|
color: rgb(0 0 0 / 85%);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
}
|
|
|
|
/* Marks a transaction type the system does not handle yet, so it reads as pending rather than broken. */
|
|
.dte-soon {
|
|
font-size: 0.78rem;
|
|
font-style: italic;
|
|
color: rgb(0 0 0 / 45%);
|
|
}
|
|
|
|
/*
|
|
* Marks a party this agent has already collected from today, on the row where it is picked.
|
|
*
|
|
* Amber, not red: a customer paying twice in a day is legitimate - arrears, or two days at once -
|
|
* so this is a second look, not an error. Blocking it would stop real work; saying nothing lets a
|
|
* whole round be credited twice.
|
|
*/
|
|
.dte-hint--again {
|
|
color: #b45309;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/*
|
|
* Where a party stands against its instalments. Three states rather than one colour, because they
|
|
* call for three different things from the clerk: ahead means take nothing, behind means take more
|
|
* than the daily amount, level means take the daily amount as usual.
|
|
*
|
|
* Behind is amber, not red - falling a few days behind is ordinary in daily collection and is the
|
|
* agent's job to recover, not an error. Red here would cry wolf on most rows.
|
|
*/
|
|
.dte-hint--ahead,
|
|
.dte-sched--ahead {
|
|
color: #15803d;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.dte-hint--behind,
|
|
.dte-sched--behind {
|
|
color: #b45309;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.dte-hint--level,
|
|
.dte-sched--level {
|
|
color: rgb(0 0 0 / 55%);
|
|
}
|
|
|
|
/* In the party panel the schedule line carries more weight than the fields around it. */
|
|
.dte-sched {
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Says why a party in the list cannot be picked, beside the party rather than in a tooltip. */
|
|
.dte-covered {
|
|
color: #15803d;
|
|
font-size: 0.8rem;
|
|
}
|
|
|
|
/*
|
|
* An amount that looks like a slip. Red rather than the amber used for arrears: arrears are ordinary
|
|
* and the agent's job to recover, while this is a figure that probably was not handed over at all,
|
|
* and once saved it cannot be taken back. It still does not block - the clerk decides.
|
|
*/
|
|
.dte-hint--overpay {
|
|
color: #b91c1c;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/*
|
|
The agent's written-down round, as the counter reads it.
|
|
|
|
Laid out as lines rather than as the input grid this replaced: there is nothing to fill in here,
|
|
only a list to check a bag of cash against, and controls would invite editing something the clerk
|
|
has no business editing.
|
|
*/
|
|
.dte-pending-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 12px;
|
|
padding: 10px 2px;
|
|
border-bottom: 1px solid rgb(0 0 0 / 8%);
|
|
|
|
&:last-of-type {
|
|
border-bottom: none;
|
|
}
|
|
|
|
/* First, and in the quieter weight: the date is context for the line, not what is being read. */
|
|
&__date {
|
|
min-width: 96px;
|
|
opacity: 0.7;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
&__code {
|
|
font-weight: 600;
|
|
min-width: 84px;
|
|
}
|
|
|
|
&__name {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
opacity: 0.75;
|
|
}
|
|
|
|
&__mode {
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Amounts are read down the column and compared, so the digits have to line up. */
|
|
&__amount {
|
|
font-variant-numeric: tabular-nums;
|
|
font-weight: 600;
|
|
min-width: 96px;
|
|
text-align: right;
|
|
}
|
|
}
|
|
|
|
/* The one figure the clerk acts on, said as a sentence so it is not read as another column total. */
|
|
.dte-expected {
|
|
margin: 14px 2px 0;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
|
|
strong {
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
}
|
|
|
|
/* Quieter than the figure above it: a note about how the screen behaves, not part of the count. */
|
|
.dte-expected--note {
|
|
font-size: 13px;
|
|
opacity: 0.65;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.dte-apply-receipt {
|
|
margin-left: 8px;
|
|
}
|
|
|
|
/* Agent Tran: what the agent owes, what the cashier has taken in, and what is left. */
|
|
.dte-money {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin: 8px 0 12px;
|
|
flex-wrap: wrap;
|
|
|
|
&__box {
|
|
flex: 1;
|
|
min-width: 160px;
|
|
padding: 10px 14px;
|
|
border: 1px solid rgb(0 0 0 / 10%);
|
|
border-radius: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
font-variant-numeric: tabular-nums;
|
|
|
|
strong {
|
|
font-size: 18px;
|
|
}
|
|
|
|
&--due {
|
|
border-color: rgb(198 40 40 / 40%);
|
|
background: rgb(198 40 40 / 4%);
|
|
}
|
|
}
|
|
|
|
&__label {
|
|
font-size: 12px;
|
|
opacity: 0.7;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
}
|
|
|
|
.dte-subhead {
|
|
margin: 16px 0 4px;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.dte-pending-row--day {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dte-day-lines {
|
|
margin-left: 24px;
|
|
max-height: 280px;
|
|
overflow-y: auto;
|
|
border-left: 3px solid rgb(25 118 210 / 30%);
|
|
padding-left: 10px;
|
|
}
|
|
|
|
.dte-status {
|
|
font-size: 12px;
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
background: rgb(237 108 2 / 12%);
|
|
color: #b45309;
|
|
|
|
&--ok {
|
|
background: rgb(46 125 50 / 12%);
|
|
color: #2e7d32;
|
|
}
|
|
}
|
|
|
|
.dte-list-arrow {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dte-same-party {
|
|
color: #c62828;
|
|
font-weight: 600;
|
|
}
|