feat(cartao): adicionar cards com status e playground tipo trello
This commit is contained in:
parent
ab15c51a1b
commit
5bb6732b81
8 changed files with 438 additions and 2 deletions
|
|
@ -5,6 +5,7 @@
|
|||
<v-tabs v-model="aba" color="primary" density="comfortable">
|
||||
<v-tab value="botao">Botão</v-tab>
|
||||
<v-tab value="indicador">Indicador</v-tab>
|
||||
<v-tab value="cartao">Cartão</v-tab>
|
||||
<v-tab value="campo">Campo</v-tab>
|
||||
<v-tab value="ola_mundo">Demo</v-tab>
|
||||
</v-tabs>
|
||||
|
|
@ -13,6 +14,7 @@
|
|||
|
||||
<BotaoPlayground v-if="aba === 'botao'" />
|
||||
<IndicadorPlayground v-else-if="aba === 'indicador'" />
|
||||
<CartaoPlayground v-else-if="aba === 'cartao'" />
|
||||
<CampoPlayground v-else-if="aba === 'campo'" />
|
||||
<OlaMundoPlayground v-else />
|
||||
</v-container>
|
||||
|
|
@ -22,6 +24,7 @@
|
|||
import { defineComponent } from 'vue'
|
||||
import BotaoPlayground from "./botao.playground.vue";
|
||||
import IndicadorPlayground from "./indicador.playground.vue";
|
||||
import CartaoPlayground from "./cartao.playground.vue";
|
||||
import CampoPlayground from "./campo.playground.vue";
|
||||
import OlaMundoPlayground from "./ola_mundo.playground.vue";
|
||||
|
||||
|
|
@ -30,12 +33,13 @@ export default defineComponent({
|
|||
components: {
|
||||
BotaoPlayground,
|
||||
IndicadorPlayground,
|
||||
CartaoPlayground,
|
||||
CampoPlayground,
|
||||
OlaMundoPlayground,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
aba: "botao" as "botao" | "indicador" | "campo" | "ola_mundo",
|
||||
aba: "botao" as "botao" | "indicador" | "cartao" | "campo" | "ola_mundo",
|
||||
};
|
||||
}
|
||||
})
|
||||
|
|
|
|||
202
src/playground/cartao.playground.vue
Normal file
202
src/playground/cartao.playground.vue
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
<template>
|
||||
<section class="stack">
|
||||
<h2>EliCartao (pipeline)</h2>
|
||||
|
||||
<div class="toolbar">
|
||||
<EliInput
|
||||
v-model="filtro"
|
||||
label="Buscar"
|
||||
placeholder="Cliente, título, valor..."
|
||||
density="compact"
|
||||
/>
|
||||
|
||||
<EliBotao @click="criar">Novo card</EliBotao>
|
||||
</div>
|
||||
|
||||
<div class="colunas">
|
||||
<section v-for="coluna in colunas" :key="coluna.status" class="coluna">
|
||||
<header class="coluna-header">
|
||||
<strong class="text-subtitle-1">{{ coluna.titulo }}</strong>
|
||||
<EliBadge :badge="coluna.itens.length" radius="pill" />
|
||||
</header>
|
||||
|
||||
<div class="cards">
|
||||
<EliCartao
|
||||
v-for="item in itensFiltrados(coluna.itens)"
|
||||
:key="item.id"
|
||||
:titulo="item.titulo"
|
||||
:status="coluna.status"
|
||||
>
|
||||
<div class="linha"><strong>Cliente:</strong> {{ item.cliente }}</div>
|
||||
<div class="linha"><strong>Valor:</strong> {{ item.valor }}</div>
|
||||
<div class="linha"><strong>Vencimento:</strong> {{ item.vencimento }}</div>
|
||||
|
||||
<template #acoes>
|
||||
<EliBotao variant="text" @click="abrir(item)">Abrir</EliBotao>
|
||||
<EliBotao variant="text" color="secondary" @click="editar(item)">
|
||||
Editar
|
||||
</EliBotao>
|
||||
</template>
|
||||
</EliCartao>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "vue";
|
||||
import { EliBadge } from "@/componentes/indicador";
|
||||
import { EliBotao } from "@/componentes/botao";
|
||||
import { EliInput } from "@/componentes/campo";
|
||||
import { EliCartao } from "@/componentes/cartao";
|
||||
import type { CartaoStatus } from "@/tipos";
|
||||
|
||||
type Card = {
|
||||
id: string;
|
||||
titulo: string;
|
||||
cliente: string;
|
||||
valor: string;
|
||||
vencimento: string;
|
||||
};
|
||||
|
||||
type Coluna = {
|
||||
status: CartaoStatus;
|
||||
titulo: string;
|
||||
itens: Card[];
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: "CartaoPlayground",
|
||||
components: { EliBadge, EliBotao, EliInput, EliCartao },
|
||||
setup() {
|
||||
const filtro = ref("");
|
||||
|
||||
const colunas = ref<Coluna[]>([
|
||||
{
|
||||
status: "novo",
|
||||
titulo: "Novo",
|
||||
itens: [
|
||||
{
|
||||
id: "1",
|
||||
titulo: "Proposta #1024",
|
||||
cliente: "ACME Ltda",
|
||||
valor: "R$ 12.500,00",
|
||||
vencimento: "10/01/2026",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
status: "rascunho",
|
||||
titulo: "Rascunho",
|
||||
itens: [
|
||||
{
|
||||
id: "2",
|
||||
titulo: "Oportunidade #204",
|
||||
cliente: "Empresa X",
|
||||
valor: "R$ 8.000,00",
|
||||
vencimento: "15/01/2026",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
status: "vendido",
|
||||
titulo: "Vendido",
|
||||
itens: [],
|
||||
},
|
||||
{
|
||||
status: "cancelado",
|
||||
titulo: "Cancelado",
|
||||
itens: [
|
||||
{
|
||||
id: "3",
|
||||
titulo: "Proposta #999",
|
||||
cliente: "Cliente Y",
|
||||
valor: "R$ 3.200,00",
|
||||
vencimento: "02/01/2026",
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
function itensFiltrados(itens: Card[]) {
|
||||
const q = filtro.value.trim().toLowerCase();
|
||||
if (!q) return itens;
|
||||
return itens.filter((i) =>
|
||||
`${i.titulo} ${i.cliente} ${i.valor}`.toLowerCase().includes(q)
|
||||
);
|
||||
}
|
||||
|
||||
function criar() {
|
||||
// Exemplo: criar card no status "novo"
|
||||
colunas.value[0]?.itens.unshift({
|
||||
id: String(Date.now()),
|
||||
titulo: "Nova oportunidade",
|
||||
cliente: "(definir)",
|
||||
valor: "R$ 0,00",
|
||||
vencimento: "--/--/----",
|
||||
});
|
||||
}
|
||||
|
||||
function abrir(_item: Card) {
|
||||
// Navegar para detalhes
|
||||
}
|
||||
|
||||
function editar(_item: Card) {
|
||||
// Abrir modal/rota de edição
|
||||
}
|
||||
|
||||
return { filtro, colunas, itensFiltrados, criar, abrir, editar };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.stack {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
grid-template-columns: minmax(260px, 420px) auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.colunas {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
}
|
||||
|
||||
.coluna {
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.coluna-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.linha {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.toolbar {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue