@7365admin1/layer-common 3.2.2-staging.160 → 3.2.2-staging.162
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/css/screens.css +25 -0
- package/components/CameraMain.vue +15 -2
- package/components/Nfc/PatrolReport/PatrolActivityTable.vue +26 -6
- package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +41 -9
- package/components/Nfc/PatrolReport/RemarksDialog.vue +39 -9
- package/components/Nfc/PatrolReport/ReportEmptyState.vue +29 -9
- package/components/Nfc/PatrolReport/ReportFilters.vue +19 -7
- package/components/Nfc/PatrolReport/ReportLocationHeader.vue +32 -6
- package/components/Nfc/PatrolReport/SummaryReportTable.vue +28 -6
- package/error.vue +30 -6
- package/package.json +1 -1
- package/pages/payment-method-linked.vue +34 -10
- package/pages/require-customer.vue +32 -8
- package/pages/require-organization-membership.vue +32 -8
- package/pages/unauthorized.vue +29 -4
package/assets/css/screens.css
CHANGED
|
@@ -398,6 +398,31 @@
|
|
|
398
398
|
opacity: 0;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
/*
|
|
402
|
+
* DISABLED. The two rules above set `background` and `color` unconditionally,
|
|
403
|
+
* and they out-specify the treatment Vuetify would otherwise give a disabled
|
|
404
|
+
* button - so a Submit that a `v-form` has genuinely gated OFF was painting
|
|
405
|
+
* the full accent fill at full opacity, identical to a live one. Measured on
|
|
406
|
+
* `OnlineFormFill` with its required field emptied: enabled and disabled came
|
|
407
|
+
* back byte-identical (`rgb(75, 116, 196)` / `rgb(255, 255, 255)` /
|
|
408
|
+
* `opacity: 1`) on BOTH themes. The gate held; nothing showed it.
|
|
409
|
+
*
|
|
410
|
+
* 0.5 is the design's own disabled step - `.app-btn:disabled` in
|
|
411
|
+
* `primitives.css` uses it - so the two button families dim by the same amount
|
|
412
|
+
* rather than inventing a second number here.
|
|
413
|
+
*
|
|
414
|
+
* Both the attribute and Vuetify's class are named: `:disabled` is what a
|
|
415
|
+
* plain `<button>` carries, `.v-btn--disabled` is what Vuetify adds, and a
|
|
416
|
+
* rule that matched only one of them would go quiet the moment the other path
|
|
417
|
+
* was used.
|
|
418
|
+
*/
|
|
419
|
+
.v-btn.screen-btn-primary:disabled,
|
|
420
|
+
.v-btn.screen-btn-primary.v-btn--disabled,
|
|
421
|
+
.v-btn.screen-btn-ghost:disabled,
|
|
422
|
+
.v-btn.screen-btn-ghost.v-btn--disabled {
|
|
423
|
+
opacity: 0.5;
|
|
424
|
+
}
|
|
425
|
+
|
|
401
426
|
/**
|
|
402
427
|
* The icon-only actions next to a primary button (download template, import,
|
|
403
428
|
* export). The design draws an icon button as a bordered square the height of
|
|
@@ -290,12 +290,25 @@ const computedHeaders = computed(() => {
|
|
|
290
290
|
{ title: "URL", key: "host" },
|
|
291
291
|
]
|
|
292
292
|
}else if(prop.type === "anpr"){
|
|
293
|
-
return [
|
|
293
|
+
return [
|
|
294
294
|
{ title: "URL", key: "host" },
|
|
295
295
|
{ title: "Type", key: "direction" },
|
|
296
296
|
]
|
|
297
297
|
}
|
|
298
|
-
//
|
|
298
|
+
// A THIRD TYPE FELL OFF THE END. Both arms above are early returns and the
|
|
299
|
+
// fallback was commented out, so `computedHeaders` resolved to `undefined`
|
|
300
|
+
// for any `type` that is neither `ip` nor `anpr` - and `:headers="undefined"`
|
|
301
|
+
// does not mean "no table", it means Vuetify derives the columns from the
|
|
302
|
+
// first item's own keys, i.e. a raw dump of every field including `_id`.
|
|
303
|
+
//
|
|
304
|
+
// `prop.headers` is the component's declared escape hatch for exactly this
|
|
305
|
+
// and nothing was reading it, so the prop was dead. Reading it makes the
|
|
306
|
+
// fallback deterministic and gives a caller a way to supply its own columns.
|
|
307
|
+
//
|
|
308
|
+
// The four commented-out entries in that prop's default (Host, Category,
|
|
309
|
+
// Guard House, Actions) are ANOTHER TEAM'S deliberate change (9610a7d,
|
|
310
|
+
// f24fa80) and are left exactly as they are.
|
|
311
|
+
return prop.headers;
|
|
299
312
|
});
|
|
300
313
|
|
|
301
314
|
const items = ref<Array<TCamera>>([]);
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The checkpoint-by-checkpoint rows of a patrol report.
|
|
3
|
+
|
|
4
|
+
Same change as the two tables beside it: off `variant="flat"` (no border on
|
|
5
|
+
either theme) and `border-thin` (a hairline the theme does not own) onto
|
|
6
|
+
`.table-card`, which is the design's table surface and styles the raw
|
|
7
|
+
`v-table`'s header row and cells.
|
|
8
|
+
|
|
9
|
+
`statusColor()` keeps returning `success`/`error`: those are the design
|
|
10
|
+
tokens by way of `utils/theme.ts`, and `utils/status.ts` does not name
|
|
11
|
+
"Skipped", so routing this through `StatusChip` would turn a red skipped
|
|
12
|
+
checkpoint neutral. That is a design decision, not a conversion.
|
|
13
|
+
-->
|
|
1
14
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
15
|
+
<div class="table-card table-card__shrink">
|
|
16
|
+
<div class="activity-table__head">
|
|
17
|
+
<span class="screen-card-title">Patrol Activity</span>
|
|
18
|
+
</div>
|
|
4
19
|
|
|
5
|
-
<
|
|
6
|
-
<v-table
|
|
20
|
+
<div>
|
|
21
|
+
<v-table>
|
|
7
22
|
<thead>
|
|
8
23
|
<tr>
|
|
9
24
|
<th>Checkpoints</th>
|
|
@@ -58,8 +73,8 @@
|
|
|
58
73
|
</tr>
|
|
59
74
|
</tbody>
|
|
60
75
|
</v-table>
|
|
61
|
-
</
|
|
62
|
-
</
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
63
78
|
</template>
|
|
64
79
|
|
|
65
80
|
<script setup lang="ts">
|
|
@@ -90,6 +105,11 @@ function handleActivityClick(activity: NFCPatrolActivity) {
|
|
|
90
105
|
</script>
|
|
91
106
|
|
|
92
107
|
<style scoped>
|
|
108
|
+
.activity-table__head {
|
|
109
|
+
padding: 14px var(--cellpad-x);
|
|
110
|
+
border-bottom: 1px solid var(--border);
|
|
111
|
+
}
|
|
112
|
+
|
|
93
113
|
.cursor-pointer {
|
|
94
114
|
cursor: pointer;
|
|
95
115
|
}
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The schedule-vs-actual pair at the top of a patrol report.
|
|
3
|
+
|
|
4
|
+
Was `variant="flat"` - a Vuetify surface with no border on either theme - and
|
|
5
|
+
the table inside it was `border-thin`, i.e. a hairline the theme does not
|
|
6
|
+
own. `.table-card` is the design's table surface: `--card` on `--border` at
|
|
7
|
+
`--r-card`, and it styles the `thead`/`tbody` of a raw `v-table` for us, so
|
|
8
|
+
the header row picks up the design's uppercase 11px/800 and the rows the
|
|
9
|
+
49px line box.
|
|
10
|
+
|
|
11
|
+
`text-body-2 text-medium-emphasis` on the tolerance was Vuetify's Roboto
|
|
12
|
+
scale plus an opacity; `--text2` is the design's secondary ink and measures
|
|
13
|
+
9.62:1 on a card.
|
|
14
|
+
-->
|
|
1
15
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<span>Patrol Route Summary: {{ summary.routeName }}</span>
|
|
5
|
-
<span class="
|
|
16
|
+
<div class="table-card table-card__shrink mb-6">
|
|
17
|
+
<div class="route-summary__head">
|
|
18
|
+
<span class="screen-card-title">Patrol Route Summary: {{ summary.routeName }}</span>
|
|
19
|
+
<span class="route-summary__tolerance">
|
|
6
20
|
Tolerance: {{ summary.tolerance }} mins
|
|
7
21
|
</span>
|
|
8
|
-
</
|
|
22
|
+
</div>
|
|
9
23
|
|
|
10
|
-
<
|
|
11
|
-
<v-table
|
|
24
|
+
<div>
|
|
25
|
+
<v-table>
|
|
12
26
|
<thead>
|
|
13
27
|
<tr>
|
|
14
28
|
<th>Time</th>
|
|
@@ -50,8 +64,8 @@
|
|
|
50
64
|
</tr>
|
|
51
65
|
</tbody>
|
|
52
66
|
</v-table>
|
|
53
|
-
</
|
|
54
|
-
</
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
55
69
|
</template>
|
|
56
70
|
|
|
57
71
|
<script setup lang="ts">
|
|
@@ -61,3 +75,21 @@ defineProps<{
|
|
|
61
75
|
summary: NFCPatrolRouteSummary;
|
|
62
76
|
}>();
|
|
63
77
|
</script>
|
|
78
|
+
|
|
79
|
+
<style scoped>
|
|
80
|
+
.route-summary__head {
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: space-between;
|
|
84
|
+
gap: 12px;
|
|
85
|
+
padding: 14px var(--cellpad-x);
|
|
86
|
+
border-bottom: 1px solid var(--border);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.route-summary__tolerance {
|
|
90
|
+
font-family: var(--font-sans);
|
|
91
|
+
font-size: var(--fs-cell);
|
|
92
|
+
color: var(--text2);
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -1,22 +1,39 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The remarks a guard left when skipping a checkpoint.
|
|
3
|
+
|
|
4
|
+
Was a bare `v-card rounded="xl"` - a 24px corner where the design's modal is
|
|
5
|
+
16px (`--r-modal`) - with a `text-h6` heading and Vuetify's default elevation
|
|
6
|
+
rather than `--shadow-modal`. `.screen-modal` is all three, and it styles its
|
|
7
|
+
own `.v-card-title`, so the `text-h6` span becomes the title element the
|
|
8
|
+
design already draws.
|
|
9
|
+
|
|
10
|
+
The close control was a tinted `variant="text"` icon button; `.screen-icon-btn`
|
|
11
|
+
is the design's bordered square, the same one every other dialog uses.
|
|
12
|
+
-->
|
|
1
13
|
<template>
|
|
2
14
|
<v-dialog :model-value="modelValue" max-width="600" persistent>
|
|
3
|
-
<v-card
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<v-
|
|
7
|
-
|
|
8
|
-
|
|
15
|
+
<v-card class="screen-modal">
|
|
16
|
+
<div class="remarks-dialog__head">
|
|
17
|
+
<v-card-title class="pa-0">Skip Checkpoint Remarks</v-card-title>
|
|
18
|
+
<v-btn
|
|
19
|
+
class="screen-icon-btn"
|
|
20
|
+
icon="mdi-close"
|
|
21
|
+
variant="flat"
|
|
22
|
+
aria-label="Close"
|
|
23
|
+
@click="close"
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
9
26
|
|
|
10
|
-
<
|
|
27
|
+
<div class="screen-modal__body px-6 pb-6">
|
|
11
28
|
<v-textarea
|
|
29
|
+
class="filter-field"
|
|
12
30
|
:model-value="remarks"
|
|
13
31
|
variant="outlined"
|
|
14
|
-
rounded="lg"
|
|
15
32
|
readonly
|
|
16
33
|
rows="4"
|
|
17
34
|
hide-details
|
|
18
35
|
/>
|
|
19
|
-
</
|
|
36
|
+
</div>
|
|
20
37
|
</v-card>
|
|
21
38
|
</v-dialog>
|
|
22
39
|
</template>
|
|
@@ -35,3 +52,16 @@ function close() {
|
|
|
35
52
|
emit("update:modelValue", false);
|
|
36
53
|
}
|
|
37
54
|
</script>
|
|
55
|
+
|
|
56
|
+
<style scoped>
|
|
57
|
+
/* The title row was a `v-card-title` with a `v-spacer` inside it. A flex row
|
|
58
|
+
with the title and the close button as its two children says the same thing
|
|
59
|
+
and lets `.screen-modal .v-card-title` reach the heading. */
|
|
60
|
+
.remarks-dialog__head {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: space-between;
|
|
64
|
+
gap: 12px;
|
|
65
|
+
padding: 20px 24px;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The patrol report's "nothing selected yet" state.
|
|
3
|
+
|
|
4
|
+
It was a bordered `v-card` with a `text-h6` heading, a `text-body-2
|
|
5
|
+
text-medium-emphasis` line and `color="grey-lighten-1"` on the icon - a fixed
|
|
6
|
+
Vuetify grey, i.e. the same light grey on the dark page.
|
|
7
|
+
|
|
8
|
+
The design already has this exact object: `.screen-empty` is the centred
|
|
9
|
+
column with the muted icon and the muted sentence, and it colours its own
|
|
10
|
+
`.v-icon`. So the card and the three type classes go and the design's one
|
|
11
|
+
class replaces them.
|
|
12
|
+
-->
|
|
1
13
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<v-icon size="64"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<p class="text-body-2 text-medium-emphasis">
|
|
8
|
-
{{ message }}
|
|
9
|
-
</p>
|
|
10
|
-
</v-card>
|
|
14
|
+
<div class="screen-empty">
|
|
15
|
+
<v-icon size="64">mdi-clipboard-text-outline</v-icon>
|
|
16
|
+
<p class="screen-empty__title">{{ title }}</p>
|
|
17
|
+
<p class="mb-0">{{ message }}</p>
|
|
18
|
+
</div>
|
|
11
19
|
</template>
|
|
12
20
|
|
|
13
21
|
<script setup lang="ts">
|
|
@@ -22,3 +30,15 @@ withDefaults(
|
|
|
22
30
|
},
|
|
23
31
|
);
|
|
24
32
|
</script>
|
|
33
|
+
|
|
34
|
+
<style scoped>
|
|
35
|
+
/* The heading keeps its emphasis over the sentence under it, but at the
|
|
36
|
+
design's card-title size rather than Vuetify's `text-h6` (20px/500 Roboto
|
|
37
|
+
metrics). `.screen-empty` already supplies the family and the muted ink. */
|
|
38
|
+
.screen-empty__title {
|
|
39
|
+
font-size: var(--fs-card-title);
|
|
40
|
+
font-weight: var(--fw-card-title);
|
|
41
|
+
color: var(--text2);
|
|
42
|
+
margin-bottom: 0;
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The route / time / date filters above a patrol report, and its Export menu.
|
|
3
|
+
|
|
4
|
+
The three fields were raw Vuetify: `rounded="lg"` is an 8px corner where the
|
|
5
|
+
design's input is `--r-inner`, and the label and placeholder sat at Vuetify's
|
|
6
|
+
own scale rather than `--fs-cell`. `.filter-field` is the design's input, and
|
|
7
|
+
it is the same class the rest of the estate's filter rows already use, so
|
|
8
|
+
these three now match every other filter on the product.
|
|
9
|
+
|
|
10
|
+
The Export button was `variant="outlined" size="large"` - 44px against the
|
|
11
|
+
design's 40 - with `rounded="lg"` again. `.screen-btn-ghost` is the design's
|
|
12
|
+
secondary button; `block` still reaches it, because the layer names
|
|
13
|
+
`.v-btn--block.screen-btn-ghost` for exactly that.
|
|
14
|
+
-->
|
|
1
15
|
<template>
|
|
2
16
|
<v-row no-gutters class="mb-6">
|
|
3
17
|
<v-col cols="12" md="3" class="pr-md-2 mb-2 mb-md-0">
|
|
@@ -7,9 +21,9 @@
|
|
|
7
21
|
item-title="title"
|
|
8
22
|
item-value="value"
|
|
9
23
|
label="Select Route"
|
|
24
|
+
class="filter-field"
|
|
10
25
|
variant="outlined"
|
|
11
26
|
density="comfortable"
|
|
12
|
-
rounded="lg"
|
|
13
27
|
hide-details
|
|
14
28
|
@update:model-value="updateFilter('route', $event)"
|
|
15
29
|
/>
|
|
@@ -25,9 +39,9 @@
|
|
|
25
39
|
:model-value="modelValue.timeRange"
|
|
26
40
|
:items="options.timeRanges"
|
|
27
41
|
label="Start Time"
|
|
42
|
+
class="filter-field"
|
|
28
43
|
variant="outlined"
|
|
29
44
|
density="comfortable"
|
|
30
|
-
rounded="lg"
|
|
31
45
|
hide-details
|
|
32
46
|
@update:model-value="updateFilter('timeRange', $event)"
|
|
33
47
|
/>
|
|
@@ -41,9 +55,9 @@
|
|
|
41
55
|
>
|
|
42
56
|
<ReportDatePicker
|
|
43
57
|
:model-value="modelValue.date"
|
|
58
|
+
class="filter-field"
|
|
44
59
|
variant="outlined"
|
|
45
60
|
density="comfortable"
|
|
46
|
-
rounded="lg"
|
|
47
61
|
hide-details
|
|
48
62
|
@update:model-value="updateFilter('date', $event)"
|
|
49
63
|
/>
|
|
@@ -56,11 +70,9 @@
|
|
|
56
70
|
<template #activator="{ props: menuProps }">
|
|
57
71
|
<v-btn
|
|
58
72
|
v-bind="menuProps"
|
|
59
|
-
|
|
73
|
+
class="screen-btn-ghost"
|
|
74
|
+
variant="flat"
|
|
60
75
|
block
|
|
61
|
-
size="large"
|
|
62
|
-
rounded="lg"
|
|
63
|
-
class="text-none"
|
|
64
76
|
prepend-icon="mdi-export"
|
|
65
77
|
>
|
|
66
78
|
Export
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The site header at the top of a patrol report.
|
|
3
|
+
|
|
4
|
+
Was a `variant="flat" rounded="lg"` card with `text-h5` and `text-body-2
|
|
5
|
+
text-medium-emphasis`. `variant="flat"` is a Vuetify surface with no border,
|
|
6
|
+
so the block had no edge on either theme; the design's card is
|
|
7
|
+
`--card` + `--border` + `--r-card` + `--shadow`, which is `.app-card`.
|
|
8
|
+
|
|
9
|
+
The two type classes are Vuetify's Roboto scale. `--fs-card-title` and
|
|
10
|
+
`--text2` are the design's, and `--text2` measures 9.62:1 on a card where
|
|
11
|
+
`--medium-emphasis` is an opacity applied to the theme ink.
|
|
12
|
+
-->
|
|
1
13
|
<template>
|
|
2
|
-
<
|
|
14
|
+
<div class="app-card text-center pa-8 mt-2">
|
|
3
15
|
<v-icon size="64" class="mb-4">mdi-office-building</v-icon>
|
|
4
|
-
<
|
|
5
|
-
<p class="
|
|
6
|
-
|
|
7
|
-
</p>
|
|
8
|
-
</v-card>
|
|
16
|
+
<p class="location-header__name">{{ location.name }}</p>
|
|
17
|
+
<p class="location-header__address mb-0">{{ location.address }}</p>
|
|
18
|
+
</div>
|
|
9
19
|
</template>
|
|
10
20
|
|
|
11
21
|
<script setup lang="ts">
|
|
@@ -15,3 +25,19 @@ defineProps<{
|
|
|
15
25
|
location: NFCPatrolReportLocation;
|
|
16
26
|
}>();
|
|
17
27
|
</script>
|
|
28
|
+
|
|
29
|
+
<style scoped>
|
|
30
|
+
.location-header__name {
|
|
31
|
+
font-family: var(--font-sans);
|
|
32
|
+
font-size: var(--fs-card-title);
|
|
33
|
+
font-weight: var(--fw-card-title);
|
|
34
|
+
color: var(--text);
|
|
35
|
+
margin-bottom: 8px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.location-header__address {
|
|
39
|
+
font-family: var(--font-sans);
|
|
40
|
+
font-size: var(--fs-cell);
|
|
41
|
+
color: var(--text2);
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
@@ -1,9 +1,26 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The per-route summary rows of a patrol report.
|
|
3
|
+
|
|
4
|
+
Same change as `PatrolRouteSummary`: `variant="flat"` drew no border on
|
|
5
|
+
either theme and `border-thin` was a hairline outside the theme.
|
|
6
|
+
`.table-card` is the design's table surface and styles the raw `v-table`'s
|
|
7
|
+
header row and cells, so the uppercase 11px/800 header and the 49px rows
|
|
8
|
+
arrive without restating either here.
|
|
9
|
+
|
|
10
|
+
The status stays `text-success` / `text-error`. Those ARE the design tokens -
|
|
11
|
+
`utils/theme.ts` maps Vuetify's `success`/`error` onto `--ok`/`--err` - and
|
|
12
|
+
swapping them to `StatusChip` would be a meaning change, not a restyle:
|
|
13
|
+
`utils/status.ts` does not name "Missed", so the shared map would render it
|
|
14
|
+
NEUTRAL and a missed patrol would stop being red. Raised, not decided here.
|
|
15
|
+
-->
|
|
1
16
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
17
|
+
<div class="table-card table-card__shrink mb-6">
|
|
18
|
+
<div class="summary-table__head">
|
|
19
|
+
<span class="screen-card-title">{{ title }}</span>
|
|
20
|
+
</div>
|
|
4
21
|
|
|
5
|
-
<
|
|
6
|
-
<v-table
|
|
22
|
+
<div>
|
|
23
|
+
<v-table>
|
|
7
24
|
<thead>
|
|
8
25
|
<tr>
|
|
9
26
|
<th>Patrol Route Name</th>
|
|
@@ -43,8 +60,8 @@
|
|
|
43
60
|
</tr>
|
|
44
61
|
</tbody>
|
|
45
62
|
</v-table>
|
|
46
|
-
</
|
|
47
|
-
</
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
48
65
|
</template>
|
|
49
66
|
|
|
50
67
|
<script setup lang="ts">
|
|
@@ -66,6 +83,11 @@ function statusClass(status: NFCPatrolReportSummaryStatus) {
|
|
|
66
83
|
</script>
|
|
67
84
|
|
|
68
85
|
<style scoped>
|
|
86
|
+
.summary-table__head {
|
|
87
|
+
padding: 14px var(--cellpad-x);
|
|
88
|
+
border-bottom: 1px solid var(--border);
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
.guard-signature {
|
|
70
92
|
width: 80px;
|
|
71
93
|
height: 40px;
|
package/error.vue
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
THE ERROR PAGE - what a user sees at their worst moment.
|
|
3
|
+
|
|
4
|
+
It was Vuetify's own chrome end to end: `text-h2` (a 60px Roboto display
|
|
5
|
+
size the design's scale does not contain), and a `variant="tonal"
|
|
6
|
+
rounded="xl" size="large"` button - a 24px-cornered 44px pill in the theme's
|
|
7
|
+
tinted wash, where every other action in the product is a 40px, 10px-cornered
|
|
8
|
+
`.screen-btn-primary`.
|
|
9
|
+
|
|
10
|
+
Nothing about the behaviour changes: same `v-app`/`v-main` wrapper (this page
|
|
11
|
+
renders OUTSIDE the app layout, so it has to bring its own), same message,
|
|
12
|
+
same route home.
|
|
13
|
+
-->
|
|
1
14
|
<script setup lang="ts">
|
|
2
15
|
import type { NuxtError } from "#app";
|
|
3
16
|
|
|
@@ -17,16 +30,14 @@ const props = defineProps({
|
|
|
17
30
|
>
|
|
18
31
|
<v-col cols="9">
|
|
19
32
|
<v-row>
|
|
20
|
-
<v-col cols="12" class="text-center
|
|
21
|
-
<
|
|
33
|
+
<v-col cols="12" class="text-center">
|
|
34
|
+
<p class="error-page__message">{{ props.error?.message }}</p>
|
|
22
35
|
</v-col>
|
|
23
36
|
<v-col cols="12">
|
|
24
37
|
<v-row no-gutters justify="center">
|
|
25
38
|
<v-btn
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class="text-none font-weight-bold"
|
|
29
|
-
variant="tonal"
|
|
39
|
+
class="screen-btn-primary"
|
|
40
|
+
variant="flat"
|
|
30
41
|
:to="{ name: 'index' }"
|
|
31
42
|
>
|
|
32
43
|
Go back
|
|
@@ -39,3 +50,16 @@ const props = defineProps({
|
|
|
39
50
|
</v-main>
|
|
40
51
|
</v-app>
|
|
41
52
|
</template>
|
|
53
|
+
|
|
54
|
+
<style scoped>
|
|
55
|
+
/* The design's page title, one step up: an error message is the only thing on
|
|
56
|
+
the screen, so it keeps display weight without borrowing Roboto's 60px. */
|
|
57
|
+
.error-page__message {
|
|
58
|
+
font-family: var(--font-sans);
|
|
59
|
+
font-size: calc(var(--fs-h1) * 1.6);
|
|
60
|
+
font-weight: var(--fw-h1);
|
|
61
|
+
letter-spacing: var(--ls-h1);
|
|
62
|
+
color: var(--text);
|
|
63
|
+
margin-bottom: 24px;
|
|
64
|
+
}
|
|
65
|
+
</style>
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@7365admin1/layer-common",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "3.2.2-staging.
|
|
5
|
+
"version": "3.2.2-staging.162",
|
|
6
6
|
"author": "7365admin1",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
8
8
|
"//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",
|
|
@@ -1,20 +1,44 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The "payment method linked" confirmation the payment window returns to.
|
|
3
|
+
|
|
4
|
+
THE DEFECT IS THE CLOSE BUTTON, NOT THE CARD. Measured before assuming:
|
|
5
|
+
`color="success lighten-1"` is Vuetify **2** syntax, but Vuetify 3 takes the
|
|
6
|
+
first token and applies it, so the card IS green - `rgb(15,138,98)` light,
|
|
7
|
+
`rgb(65,199,149)` dark. Only `lighten-1` is dead, and it changes nothing.
|
|
8
|
+
The green card stays: a success page is green on purpose, and swapping it for
|
|
9
|
+
a neutral surface would be a design decision, not a conversion.
|
|
10
|
+
|
|
11
|
+
What was wrong is `color="white" variant="tonal"` on Close. `tonal` paints
|
|
12
|
+
its tint on an OVERLAY, so the button's own background measured
|
|
13
|
+
`rgba(0,0,0,0)` and all that reached the glass was white text - on the green
|
|
14
|
+
card. Light: white on `rgb(15,138,98)` = 4.35:1. **Dark: white on
|
|
15
|
+
`rgb(65,199,149)` = 2.12:1**, which is the worst reading on this page and the
|
|
16
|
+
reason it needed touching at all. `.screen-btn-ghost` is the design's
|
|
17
|
+
secondary button - the card surface with `--text2` ink and a `--border` - so
|
|
18
|
+
it reads on green in both themes, and it is the 40px/10px button the rest of
|
|
19
|
+
the product uses rather than a 44px 24px-cornered pill.
|
|
20
|
+
|
|
21
|
+
The title had the same defect in the other direction: a literal `text-white`
|
|
22
|
+
on a fill that changes with the theme. See the comment on it below.
|
|
23
|
+
|
|
24
|
+
Behaviour is unchanged: same `window.close()`.
|
|
25
|
+
-->
|
|
1
26
|
<template>
|
|
2
27
|
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
-
<v-card class="pa-4" elevation="4" color="success
|
|
4
|
-
|
|
28
|
+
<v-card class="pa-4" elevation="4" color="success">
|
|
29
|
+
<!-- `text-white` was a literal on a THEMED fill, and the fill changes with
|
|
30
|
+
the theme: white on dark's `rgb(65,199,149)` measures **2.14:1**.
|
|
31
|
+
Dropping it lets the card use its own paired ink - Vuetify sets
|
|
32
|
+
`on-success` from `color="success"` - which follows the fill. -->
|
|
33
|
+
<v-card-title class="d-flex align-center">
|
|
5
34
|
<v-icon class="mr-2">mdi-check-circle</v-icon>
|
|
6
35
|
Successfully Linked Payment Method
|
|
7
36
|
</v-card-title>
|
|
8
37
|
|
|
9
38
|
<v-card-actions class="d-flex justify-center">
|
|
10
|
-
<v-btn
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
rounded="xl"
|
|
14
|
-
size="large"
|
|
15
|
-
@click="closeWindow"
|
|
16
|
-
>Close</v-btn
|
|
17
|
-
>
|
|
39
|
+
<v-btn class="screen-btn-ghost" variant="flat" @click="closeWindow">
|
|
40
|
+
Close
|
|
41
|
+
</v-btn>
|
|
18
42
|
</v-card-actions>
|
|
19
43
|
</v-card>
|
|
20
44
|
</v-row>
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The "you must have a customer" gate.
|
|
3
|
+
|
|
4
|
+
Was Vuetify's chrome: `text-subtitle-1` for the sentence, `text-subtitle-2`
|
|
5
|
+
on the buttons, and `variant="tonal" rounded="xl"` - a 24px-cornered pill in
|
|
6
|
+
the theme's tinted wash, where the product's action is a 40px, 10px-cornered
|
|
7
|
+
button. The sentence is now `--text2` (9.62:1 on a card) at the design's
|
|
8
|
+
reading size, and the actions are the design's primary and ghost buttons.
|
|
9
|
+
|
|
10
|
+
No behaviour change: same handlers, same destinations, same `plain` layout.
|
|
11
|
+
-->
|
|
1
12
|
<template>
|
|
2
13
|
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
-
<v-col cols="12" lg="6" md="6" sm="6" class="text-center
|
|
14
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center gate-page__message">
|
|
4
15
|
You must have a customer to view this page. Please join or contact your
|
|
5
16
|
administrator for access.
|
|
6
17
|
<v-row no-gutters justify="center" align="center" class="mt-2">
|
|
7
18
|
<v-btn
|
|
19
|
+
class="screen-btn-ghost"
|
|
20
|
+
variant="flat"
|
|
8
21
|
@click="goToAccount"
|
|
9
|
-
rounded="xl"
|
|
10
|
-
variant="tonal"
|
|
11
|
-
class="text-none text-subtitle-2"
|
|
12
22
|
>
|
|
13
23
|
Go to Organization Page
|
|
14
24
|
</v-btn>
|
|
15
|
-
<span class="mx-2">or</span>
|
|
25
|
+
<span class="mx-2 gate-page__or">or</span>
|
|
16
26
|
<v-btn
|
|
27
|
+
class="screen-btn-primary"
|
|
28
|
+
variant="flat"
|
|
17
29
|
@click="createCustomer"
|
|
18
|
-
rounded="xl"
|
|
19
|
-
variant="tonal"
|
|
20
|
-
class="text-none text-subtitle-2"
|
|
21
30
|
>
|
|
22
31
|
Create an Customer
|
|
23
32
|
</v-btn>
|
|
@@ -54,3 +63,18 @@ function createCustomer() {
|
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
</script>
|
|
66
|
+
|
|
67
|
+
<style scoped>
|
|
68
|
+
.gate-page__message {
|
|
69
|
+
font-family: var(--font-sans);
|
|
70
|
+
font-size: var(--fs-cell);
|
|
71
|
+
color: var(--text2);
|
|
72
|
+
line-height: 1.6;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.gate-page__or {
|
|
76
|
+
font-family: var(--font-sans);
|
|
77
|
+
font-size: var(--fs-cell);
|
|
78
|
+
color: var(--muted);
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The "you must be a member of an organization" gate.
|
|
3
|
+
|
|
4
|
+
Was Vuetify's chrome: `text-subtitle-1` for the sentence, `text-subtitle-2`
|
|
5
|
+
on the buttons, and `variant="tonal" rounded="xl"` - a 24px-cornered pill in
|
|
6
|
+
the theme's tinted wash, where the product's action is a 40px, 10px-cornered
|
|
7
|
+
button. The sentence is now `--text2` (9.62:1 on a card) at the design's
|
|
8
|
+
reading size, and the actions are the design's primary and ghost buttons.
|
|
9
|
+
|
|
10
|
+
No behaviour change: same handlers, same destinations, same `plain` layout.
|
|
11
|
+
-->
|
|
1
12
|
<template>
|
|
2
13
|
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
-
<v-col cols="12" lg="6" md="6" sm="6" class="text-center
|
|
14
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center gate-page__message">
|
|
4
15
|
You must be a member of an organization to view this page. Please join or
|
|
5
16
|
contact your administrator for access.
|
|
6
17
|
<v-row no-gutters justify="center" align="center" class="mt-2">
|
|
7
18
|
<v-btn
|
|
19
|
+
class="screen-btn-ghost"
|
|
20
|
+
variant="flat"
|
|
8
21
|
@click="goToAccount"
|
|
9
|
-
rounded="xl"
|
|
10
|
-
variant="tonal"
|
|
11
|
-
class="text-none text-subtitle-2"
|
|
12
22
|
>
|
|
13
23
|
Go to Account Page
|
|
14
24
|
</v-btn>
|
|
15
|
-
<span class="mx-2">or</span>
|
|
25
|
+
<span class="mx-2 gate-page__or">or</span>
|
|
16
26
|
<v-btn
|
|
27
|
+
class="screen-btn-primary"
|
|
28
|
+
variant="flat"
|
|
17
29
|
@click="createOrg"
|
|
18
|
-
rounded="xl"
|
|
19
|
-
variant="tonal"
|
|
20
|
-
class="text-none text-subtitle-2"
|
|
21
30
|
>
|
|
22
31
|
Create an Organization
|
|
23
32
|
</v-btn>
|
|
@@ -45,3 +54,18 @@ function createOrg() {
|
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
</script>
|
|
57
|
+
|
|
58
|
+
<style scoped>
|
|
59
|
+
.gate-page__message {
|
|
60
|
+
font-family: var(--font-sans);
|
|
61
|
+
font-size: var(--fs-cell);
|
|
62
|
+
color: var(--text2);
|
|
63
|
+
line-height: 1.6;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.gate-page__or {
|
|
67
|
+
font-family: var(--font-sans);
|
|
68
|
+
font-size: var(--fs-cell);
|
|
69
|
+
color: var(--muted);
|
|
70
|
+
}
|
|
71
|
+
</style>
|
package/pages/unauthorized.vue
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The "you are not a member of an organization" gate.
|
|
3
|
+
|
|
4
|
+
Was Vuetify's chrome: `text-subtitle-1` for the sentence, `text-subtitle-2`
|
|
5
|
+
on the buttons, and `variant="tonal" rounded="xl"` - a 24px-cornered pill in
|
|
6
|
+
the theme's tinted wash, where the product's action is a 40px, 10px-cornered
|
|
7
|
+
button. The sentence is now `--text2` (9.62:1 on a card) at the design's
|
|
8
|
+
reading size, and the actions are the design's primary and ghost buttons.
|
|
9
|
+
|
|
10
|
+
No behaviour change: same handlers, same destinations, same `plain` layout.
|
|
11
|
+
-->
|
|
1
12
|
<template>
|
|
2
13
|
<v-row no-gutters class="fill-height" align="center" justify="center">
|
|
3
|
-
<v-col cols="12" lg="6" md="6" sm="6" class="text-center
|
|
14
|
+
<v-col cols="12" lg="6" md="6" sm="6" class="text-center gate-page__message">
|
|
4
15
|
You must be a member of an organization to view this page. Please join or
|
|
5
16
|
contact your administrator for access.
|
|
6
17
|
<v-row no-gutters justify="center" class="mt-2">
|
|
7
18
|
<v-btn
|
|
19
|
+
class="screen-btn-primary"
|
|
20
|
+
variant="flat"
|
|
8
21
|
@click="goToAccount"
|
|
9
|
-
rounded="xl"
|
|
10
|
-
variant="tonal"
|
|
11
|
-
class="text-none text-subtitle-2"
|
|
12
22
|
>
|
|
13
23
|
Go to Account Page
|
|
14
24
|
</v-btn>
|
|
@@ -27,3 +37,18 @@ function goToAccount() {
|
|
|
27
37
|
window.location.href = `${APP_ACCOUNT}/home`;
|
|
28
38
|
}
|
|
29
39
|
</script>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
.gate-page__message {
|
|
43
|
+
font-family: var(--font-sans);
|
|
44
|
+
font-size: var(--fs-cell);
|
|
45
|
+
color: var(--text2);
|
|
46
|
+
line-height: 1.6;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.gate-page__or {
|
|
50
|
+
font-family: var(--font-sans);
|
|
51
|
+
font-size: var(--fs-cell);
|
|
52
|
+
color: var(--muted);
|
|
53
|
+
}
|
|
54
|
+
</style>
|