|
| 1 | +<script setup lang="ts"> |
| 2 | +const billAmount = ref<number>(); |
| 3 | +const tipPercentage = ref<number>(15); |
| 4 | +const numberOfPeople = ref<number>(1); |
| 5 | +
|
| 6 | +const tipAmount = computed(() => { |
| 7 | + if (billAmount.value === undefined || tipPercentage.value === undefined) { |
| 8 | + return 0; |
| 9 | + } |
| 10 | + return (billAmount.value * tipPercentage.value) / 100; |
| 11 | +}); |
| 12 | +
|
| 13 | +const totalAmount = computed(() => { |
| 14 | + if (billAmount.value === undefined) { |
| 15 | + return 0; |
| 16 | + } |
| 17 | + return billAmount.value + tipAmount.value; |
| 18 | +}); |
| 19 | +
|
| 20 | +const amountPerPerson = computed(() => { |
| 21 | + if (totalAmount.value === 0 || numberOfPeople.value === undefined || numberOfPeople.value <= 0) { |
| 22 | + return 0; |
| 23 | + } |
| 24 | + return totalAmount.value / numberOfPeople.value; |
| 25 | +}); |
| 26 | +
|
| 27 | +function formatCurrency(value: number) { |
| 28 | + return new Intl.NumberFormat().format(value); |
| 29 | +} |
| 30 | +
|
| 31 | +const tipAmountFormatted = computed(() => formatCurrency(tipAmount.value)); |
| 32 | +const totalAmountFormatted = computed(() => formatCurrency(totalAmount.value)); |
| 33 | +const amountPerPersonFormatted = computed(() => formatCurrency(amountPerPerson.value)); |
| 34 | +</script> |
| 35 | + |
| 36 | +<template> |
| 37 | + <div style="margin: 0 auto; max-width: 600px"> |
| 38 | + <c-card mb-3 title="Bill Details"> |
| 39 | + <n-form label-placement="left" label-width="150px" label-align="left"> |
| 40 | + <n-form-item label="Bill Amount:"> |
| 41 | + <n-input-number v-model:value="billAmount" :min="0" placeholder="Total Bill" /> |
| 42 | + </n-form-item> |
| 43 | + |
| 44 | + <n-form-item label="Tip Percentage:"> |
| 45 | + <n-input-number v-model:value="tipPercentage" :min="0" placeholder="Tip %"> |
| 46 | + <template #suffix> |
| 47 | + % |
| 48 | + </template> |
| 49 | + </n-input-number> |
| 50 | + </n-form-item> |
| 51 | + |
| 52 | + <n-form-item label="Number of person:"> |
| 53 | + <n-input-number v-model:value="numberOfPeople" :min="1" placeholder="People" /> |
| 54 | + </n-form-item> |
| 55 | + </n-form> |
| 56 | + </c-card> |
| 57 | + |
| 58 | + <c-card mb-3 title="Results"> |
| 59 | + <input-copyable label="Tip Amount:" :value="tipAmountFormatted" readonly label-position="left" label-width="150px" mb-1 /> |
| 60 | + <input-copyable label="Total Bill:" :value="totalAmountFormatted" readonly label-position="left" label-width="150px" mb-1 /> |
| 61 | + <input-copyable label="Amount Per Person:" :value="amountPerPersonFormatted" readonly label-position="left" label-width="150px" mb-1 /> |
| 62 | + </c-card> |
| 63 | + |
| 64 | + <c-card title="Quick Tip %"> |
| 65 | + <n-space justify="center"> |
| 66 | + <n-button v-for="tip in [10, 15, 18, 20, 25]" :key="tip" size="small" @click="tipPercentage = tip"> |
| 67 | + {{ tip }}% |
| 68 | + </n-button> |
| 69 | + </n-space> |
| 70 | + </c-card> |
| 71 | + </div> |
| 72 | +</template> |
0 commit comments