|
|
@@ -1,261 +0,0 @@
|
|
|
-<template>
|
|
|
- <q-card class="panel-card panel-card--soft" flat>
|
|
|
- <div class="panel-title">Disponibilidade do Período</div>
|
|
|
-
|
|
|
- <div class="availability-list">
|
|
|
- <div
|
|
|
- v-for="item in decoratedItems"
|
|
|
- :key="item.label"
|
|
|
- class="availability-item"
|
|
|
- >
|
|
|
- <div class="availability-track">
|
|
|
- <div
|
|
|
- class="availability-bar"
|
|
|
- :style="{
|
|
|
- backgroundColor: item.color,
|
|
|
- }"
|
|
|
- >
|
|
|
- <div class="availability-track-meta">
|
|
|
- <div class="availability-bar-label-wrap">
|
|
|
- <span
|
|
|
- class="availability-bar-value-dot"
|
|
|
- :style="{
|
|
|
- color: item.textColor,
|
|
|
- backgroundColor: item.textColor,
|
|
|
- }"
|
|
|
- />
|
|
|
-
|
|
|
- <span class="availability-bar-label">{{ item.label }}</span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <span class="availability-bar-value-wrap">
|
|
|
- <span
|
|
|
- class="availability-bar-value"
|
|
|
- :style="{ color: item.textColor }"
|
|
|
- >{{ item.valueLabel }}</span
|
|
|
- >
|
|
|
- </span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="availability-total-track">
|
|
|
- <div
|
|
|
- v-for="item in items"
|
|
|
- :key="`${item.label}-total`"
|
|
|
- :style="{
|
|
|
- width: `${item.percentage}%`,
|
|
|
- backgroundColor: item.color,
|
|
|
- }"
|
|
|
- class="availability-total-segment"
|
|
|
- />
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="availability-total">
|
|
|
- {{ totalLabel }}
|
|
|
- </div>
|
|
|
- </q-card>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { computed } from "vue";
|
|
|
-import { formatInteger } from "src/helpers/utils";
|
|
|
-
|
|
|
-const props = defineProps({
|
|
|
- isAllPropertiesSelected: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- items: {
|
|
|
- type: Array,
|
|
|
- default: () => [],
|
|
|
- },
|
|
|
- totalCapacityDays: {
|
|
|
- type: Number,
|
|
|
- default: 0,
|
|
|
- },
|
|
|
-});
|
|
|
-
|
|
|
-const totalLabel = computed(() =>
|
|
|
- props.isAllPropertiesSelected
|
|
|
- ? "Total: 100% do período consolidado"
|
|
|
- : `Total: ${formatInteger(props.totalCapacityDays)} dias no período`,
|
|
|
-);
|
|
|
-
|
|
|
-const clampChannel = (value) => Math.max(0, Math.min(255, value));
|
|
|
-
|
|
|
-const darkenColor = (hexColor, amount = 0.42) => {
|
|
|
- const hex = String(hexColor ?? "").replace("#", "");
|
|
|
-
|
|
|
- if (hex.length !== 6) {
|
|
|
- return "#173235";
|
|
|
- }
|
|
|
-
|
|
|
- const channels = [0, 2, 4].map((start) =>
|
|
|
- Number.parseInt(hex.slice(start, start + 2), 16),
|
|
|
- );
|
|
|
- const darkened = channels.map((channel) =>
|
|
|
- clampChannel(Math.round(channel * (1 - amount))),
|
|
|
- );
|
|
|
-
|
|
|
- return `#${darkened.map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
|
|
|
-};
|
|
|
-
|
|
|
-const decoratedItems = computed(() =>
|
|
|
- props.items.map((item) => ({
|
|
|
- ...item,
|
|
|
- textColor: darkenColor(item.color),
|
|
|
- })),
|
|
|
-);
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-.panel-card {
|
|
|
- padding: 18px;
|
|
|
- border-radius: 14px;
|
|
|
- background: #ffffff;
|
|
|
- border: 1px solid #d9e3e7;
|
|
|
- min-height: 300px;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.panel-card--soft {
|
|
|
- background: #f0f3f5;
|
|
|
-}
|
|
|
-
|
|
|
-.panel-title {
|
|
|
- margin-bottom: 16px;
|
|
|
- font-size: 19px;
|
|
|
- font-weight: 400;
|
|
|
- color: #08514c;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-list {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 16px;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-item {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-track {
|
|
|
- position: relative;
|
|
|
- width: 100%;
|
|
|
- min-height: 42px;
|
|
|
- overflow: hidden;
|
|
|
- background: #dde5e8;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-bar {
|
|
|
- width: 100%;
|
|
|
- min-height: 42px;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-track-meta {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- gap: 12px;
|
|
|
- width: 100%;
|
|
|
- min-width: 0;
|
|
|
- min-height: 42px;
|
|
|
- padding: 0 14px;
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- color: #173235;
|
|
|
- font-size: 13px;
|
|
|
- font-weight: 700;
|
|
|
- white-space: nowrap;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-bar-label {
|
|
|
- text-align: left;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-bar-label-wrap,
|
|
|
-.availability-bar-value-wrap {
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: flex-start;
|
|
|
- gap: 8px;
|
|
|
- min-width: 0;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-bar-value {
|
|
|
- text-align: right;
|
|
|
- overflow-wrap: anywhere;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-bar-value-dot {
|
|
|
- display: inline-flex;
|
|
|
- width: 8px;
|
|
|
- height: 8px;
|
|
|
- border-radius: 50%;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-total-track {
|
|
|
- display: flex;
|
|
|
- width: 100%;
|
|
|
- height: 18px;
|
|
|
- margin-top: 18px;
|
|
|
- overflow: hidden;
|
|
|
- background: #dde5e8;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-total-segment {
|
|
|
- height: 100%;
|
|
|
- min-width: 0;
|
|
|
- vertical-align: middle;
|
|
|
-}
|
|
|
-
|
|
|
-.availability-total {
|
|
|
- margin-top: 18px;
|
|
|
- color: #657177;
|
|
|
- font-size: 14px;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-@media (max-width: 640px) {
|
|
|
- .availability-list {
|
|
|
- gap: 12px;
|
|
|
- }
|
|
|
-
|
|
|
- .availability-track,
|
|
|
- .availability-bar {
|
|
|
- min-height: 48px;
|
|
|
- }
|
|
|
-
|
|
|
- .availability-track-meta {
|
|
|
- flex-direction: column;
|
|
|
- align-items: flex-start;
|
|
|
- justify-content: center;
|
|
|
- gap: 8px;
|
|
|
- min-height: 48px;
|
|
|
- padding: 0 12px;
|
|
|
- font-size: 12px;
|
|
|
- white-space: normal;
|
|
|
- }
|
|
|
-
|
|
|
- .availability-bar-value-wrap {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .availability-bar-value {
|
|
|
- text-align: left;
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|