Skip to content

Commit

Permalink
Merge pull request #20 from Billing-Wise/K5P-68/feat/청구컴포넌트
Browse files Browse the repository at this point in the history
[feat] 청구컴포넌트
  • Loading branch information
Koneweekk authored Jul 30, 2024
2 parents accee0c + f28cef2 commit 1f0b87f
Show file tree
Hide file tree
Showing 45 changed files with 2,136 additions and 39 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Billing Wise</title>
</head>
Expand Down
Binary file removed public/favicon.ico
Binary file not shown.
Binary file added public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/scss/component/modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

.modal-content {
@include flex-box(column, center, 20px);
width: 400px;
width: 500px;
max-height: 100%;
padding: 0px 30px;
border-radius : 10px;
Expand Down
8 changes: 8 additions & 0 deletions src/assets/scss/component/table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
}
}

.status-sticker {
@include flex-box(row, center, 0px);
@include white-text(14px);
padding: 3px 5px;
border-radius: 20px;
}


/* 웹킷 브라우저의 스크롤바 숨기기 */
.table-box::-webkit-scrollbar {
display: none;
Expand Down
21 changes: 21 additions & 0 deletions src/components/common/btn/ResetIconBtn.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<i class="bi bi-calendar4-range calendar-icon" @click="triggerDateInput"></i>
</template>

<script>
export default {
name: 'ResetIconBtnVue',
props: {
func: Function
},
};
</script>

<style lang="scss" scoped>
.calendar-icon {
@include base-icon;
// cursor: pointer;
color: white;
font-size: 20px;
}
</style>
28 changes: 28 additions & 0 deletions src/components/common/btn/WarningBtn.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<button class="theme-btn" @click="func">
<span>{{ title }}</span>
</button>
</template>

<script>
export default {
name: 'ThmemBtnVue',
props: {
title: String,
func: Function
}
}
</script>

<style lang="scss" scoped>
.theme-btn {
@include flex-box(row, center, 10px);
@include base-button();
padding: 10px 20px;
background-color: $warning-color;
color: white;
border: none;
font-size: 18px;
font-weight: bold;
}
</style>
36 changes: 36 additions & 0 deletions src/components/common/input/CalendarDateInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<i class="bi bi-calendar4-range calendar-icon" @click="triggerDateInput"></i>
<input
type="date"
ref="dateInput"
:value="modelValue"
@input="updateValue($event.target.value)"
style="visibility: hidden; position: absolute;"
>
</template>

<script>
export default {
name: 'CalendarDateInputVue',
props: {
modelValue: String,
},
methods: {
triggerDateInput() {
this.$refs.dateInput.showPicker();
},
updateValue(value) {
this.$emit('update:modelValue', value);
},
},
};
</script>

<style lang="scss" scoped>
.calendar-icon {
@include base-icon;
// cursor: pointer;
color: white;
font-size: 20px;
}
</style>
3 changes: 1 addition & 2 deletions src/components/common/input/FileInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<script>
export default {
name: 'FileInputtVue',
name: 'FileInputVue',
props: {
'modelValue': File,
},
Expand All @@ -33,7 +33,6 @@ export default {
this.$emit('update:modelValue', file);
}
}
}
</script>

Expand Down
1 change: 1 addition & 0 deletions src/components/common/modal/ModalFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default {
border-top: $theme-color solid 2px;
p {
color: tomato;
font-size: 14px;
font-weight: bold;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/common/select/TitleSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,6 @@ export default {
@include flex-box(column, center, 10px);
@include select-list;
top: calc(100% + 10px);
width:90%
}
</style>
7 changes: 5 additions & 2 deletions src/components/common/table/TableHaeder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<th v-for="(column, key) in showColumns" :key="key">
<div class="column-item">
<span>{{ column.name }}</span>
<i :class="column.sort ? sortIcon[column.sort] : nonSortIcon" @click="changeSort(column)"></i>
<i
v-if="!column.notSortable"
:class="column.sort ? sortIcon[column.sort] : nonSortIcon"
@click="changeSort(column)"></i>
</div>
</th>
</tr>
Expand All @@ -17,7 +20,7 @@ export default {
type: Object,
required: true
},
excludeColumnArr : Array
excludeColumnArr: Array
},
data() {
return {
Expand Down
2 changes: 1 addition & 1 deletion src/components/contract/ContractInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
import { mapStores } from 'pinia';
import { useContractDetailStore } from '@/stores/contract/contractDetail';
import { getContract } from '@/utils/contract';
import TitleInfoVue from '../common/info/TitleInfo.vue';
import { toDateFromDateTime } from '@/utils/date';
import TitleInfoVue from '../common/info/TitleInfo.vue';
export default {
name: 'ContractInfoVue',
Expand Down
104 changes: 104 additions & 0 deletions src/components/contract/modal/InvoiceCreateModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<transition name="fade">
<div v-if="isVisible" class="modal-overlay">
<div class="modal-content">
<ModalHeaderVue :title="title" :closeModal="closeModal" />
<div class="modal-main">
<TitleSelectVue title="결제 수단" :selectedIdx="invoiceCreateStore.paymentTypeIdx"
:keywordArr="invoiceCreateStore.paymentType" :choiceFunc="setPaymentType" />
<InfoInputVue title="청구금" v-model="chargeAmount" type="number" />
<InfoInputVue title="약정일" type="date" v-model="contractDate" />
<InfoInputVue title="납부기한" type="date" v-model="dueDate" />
</div>
<ModalFooterVue :title="title" :errorMsg="errorMsg" :func="createInvoice" />
</div>
</div>
</transition>
</template>

<script>
import ModalHeaderVue from '../../common/modal/ModalHeader.vue';
import ModalFooterVue from '../../common/modal/ModalFooter.vue';
import InfoInputVue from '@/components/common/input/InfoInput.vue';
import TitleSelectVue from '@/components/common/select/TitleSelect.vue';
import { useInvoiceCreateStore } from '@/stores/invoice/invoiceCreate';
import { useContractDetailStore } from '@/stores/contract/contractDetail';
import { mapStores } from 'pinia';
import { createInvoice } from '@/utils/invoice';
export default {
name: 'InvoiceCreateModalVue',
components: {
ModalHeaderVue,
ModalFooterVue,
InfoInputVue,
TitleSelectVue
},
props: {
'isVisible': Boolean,
'closeModal': Function,
},
data() {
return {
title: '청구 생성',
errorMsg: '',
}
},
computed: {
...mapStores(useInvoiceCreateStore),
...mapStores(useContractDetailStore),
chargeAmount: {
get() {
return this.invoiceCreateStore.data.chargeAmount;
},
set(value) {
this.invoiceCreateStore.data.chargeAmount = value;
}
},
contractDate: {
get() {
return this.invoiceCreateStore.data.contractDate;
},
set(value) {
this.invoiceCreateStore.data.contractDate = value;
}
},
dueDate: {
get() {
return this.invoiceCreateStore.data.dueDate;
},
set(value) {
this.invoiceCreateStore.data.dueDate = value;
}
},
},
watch: {
isVisible(newVal) {
if (newVal) this.selectContact();
},
},
methods: {
// 현재 데이터 표시
selectContact() {
this.invoiceCreateStore.$reset();
this.invoiceCreateStore.setContract(this.contractDetailStore.data)
},
setPaymentType(idx) {
this.invoiceCreateStore.setPaymentTypeIdx(idx)
},
async createInvoice() {
const result = await createInvoice();
if (result.code === 200) {
this.$router.push(`/invoice/${result.data}`);
} else {
this.errorMsg = result.message;
}
},
},
}
</script>

<style lang="scss" scoped>
@import '@/assets/scss/component/modal.scss';
</style>
67 changes: 67 additions & 0 deletions src/components/contract/table/ContractInvoiceTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<table class="contract-table">
<thead>
<TableHaederVue :store="invoiceListStore"
:excludeColumnArr="['contractId', 'itemName', 'memberName', 'createdAt', 'paymentType']" />
<ContractInvoiceTableFilterVue />
</thead>
<tbody>
<ContractInvoiceTableRowVue v-for="(invoice, idx) in invoiceListStore.invoiceList" :key="idx" :invoiceData="invoice" />
</tbody>
</table>
</template>

<script>
import { mapActions, mapStores } from 'pinia';
import { useInvoiceListStore } from '@/stores/invoice/invoiceList';
import { getInvoiceList } from '@/utils/invoice';
import TableHaederVue from '@/components/common/table/TableHaeder.vue';
import ContractInvoiceTableFilterVue from './ContractInvoiceTableFilter.vue';
import ContractInvoiceTableRowVue from './ContractInvoiceTableRow.vue';
export default {
name: 'ContractInvoiceTableVue',
components: {
TableHaederVue,
ContractInvoiceTableFilterVue,
ContractInvoiceTableRowVue
},
computed: {
...mapStores(useInvoiceListStore),
},
methods: {
...mapActions(useInvoiceListStore, ['setColumnSort']),
async getInvoiceList() {
const result = await getInvoiceList();
if (result.code !== 200) {
// 예외 처리
}
},
setupWatchers() {
this.$watch('invoiceListStore.size', this.getInvoiceList);
this.$watch('invoiceListStore.page', this.getInvoiceList);
this.$watch('invoiceListStore.columns', this.getInvoiceList, { deep: true });
this.invoiceListStore.filters.forEach(filter => {
if (filter.data !== 'itemName' && filter.data !== 'memberName') {
this.$watch(() => filter.value, this.getInvoiceList);
}
});
},
},
async mounted() {
this.invoiceListStore.$reset();
this.invoiceListStore.setFilter('contractId', this.$route.params.id);
await this.getInvoiceList();
this.setupWatchers();
}
}
</script>

<style lang="scss" scoped>
@import "@/assets/scss/component/table.scss";
.contract-table {
@include base-table();
}
</style>
Loading

0 comments on commit 1f0b87f

Please sign in to comment.