-accouting Wep
All checks were successful
Build Docker Image / Build Docker Image (push) Successful in 8m54s

This commit is contained in:
x2Skyz
2025-11-21 15:01:21 +07:00
parent 1c7729ab99
commit 45259f7b8d
21 changed files with 590 additions and 350 deletions

View File

@@ -19,14 +19,14 @@
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
<div class="text-gray-500 text-sm">รายรับทั้งหมด</div>
<div class="text-3xl font-bold text-green-600 mt-1">
{{ 11000 | number:'1.0-2' }} บาท
{{ myActSumData.summary.totalIncome || 0 | number:'1.0-2' }} บาท
</div>
</div>
<div class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm hover:shadow-md transition">
<div class="text-gray-500 text-sm">รายจ่ายทั้งหมด</div>
<div class="text-3xl font-bold text-red-600 mt-1">
{{ 1000 | number:'1.0-2' }} บาท
{{ myActSumData.summary.totalExpense || 0 | number:'1.0-2' }} บาท
</div>
</div>
@@ -34,9 +34,9 @@
<div class="text-gray-500 text-sm">คงเหลือ</div>
<div
class="text-3xl font-bold mt-1"
[ngClass]="100 >= 0 ? 'text-blue-600' : 'text-red-600'"
[ngClass]="myActSumData.summary.netProfit >= 0 ? 'text-blue-600' : 'text-red-600'"
>
{{ 10000 | number:'1.0-2' }} บาท
{{ myActSumData.summary.netProfit | number:'1.0-2' }} บาท
</div>
</div>
@@ -81,63 +81,129 @@
</article>
</section> -->
<section class="ledger-grid">
<article class="panel quick-log">
<div class="panel__header">
<div>
<h2>บันทึกรายการแบบรวดเร็ว</h2>
<p>จดรายรับรายจ่ายภายในไม่กี่คลิก</p>
</div>
</div>
<form class="quick-log__form">
<label>
<span>ประเภท</span>
<div class="quick-log__toggle">
<button type="button" class="toggle-btn" [ngClass]="{ 'is-active': mode == 'i' }" (click)="mode = 'i'">รายรับ</button>
<button type="button" class="toggle-btn" [ngClass]="{ 'is-active': mode == 'e' }" (click)="mode = 'e'">รายจ่าย</button>
</div>
</label>
<label>
<span>วันที่</span>
<!-- <input type="text" disabled placeholder="10/04/2025 เวลา 12:00"/> -->
<div class="ledger-grid" [formGroup]="saveFrm">
<form class="panel quick-log" [formGroup]="saveFrm">
<div class="panel__header">
<div>
<h2>บันทึกรายการแบบรวดเร็ว</h2>
<p>จดรายรับรายจ่ายภายในไม่กี่คลิก</p>
</div>
</div>
<input type="datetime-local"/>
<!-- เปลี่ยน form ด้านในเป็น div แทน เพื่อไม่ให้ form ซ้อน form -->
<div class="quick-log__form">
<!-- 1. ส่วนเลือกประเภท (รายรับ/รายจ่าย) -->
<label>
<span>ประเภท</span>
<div class="quick-log__toggle">
<button type="button" class="toggle-btn" [ngClass]="{ 'is-active': mode == 'i' }" (click)="mode = 'i'; saveFrm.get('actcat')?.reset()">รายรับ</button>
<button type="button" class="toggle-btn" [ngClass]="{ 'is-active': mode == 'e' }" (click)="mode = 'e'; saveFrm.get('actcat')?.reset()">รายจ่าย</button>
</div>
</label>
<!-- 2. ส่วนวันที่ -->
<div class="mb-2">
<label>
<span>วันที่ <span class="text-red-500">*</span></span>
<input type="datetime-local" formControlName="actacpdtm"
[class.border-red-500]="saveFrm.get('actacpdtm')?.invalid && (saveFrm.get('actacpdtm')?.value || saveFrm.get('actacpdtm')?.touched)"/>
</label>
<div class="quick-log__grid">
<label>
<span>หมวดหมู่</span>
<!-- Validate วันที่ -->
@if (saveFrm.get('actacpdtm')?.invalid && (saveFrm.get('actacpdtm')?.value || saveFrm.get('actacpdtm')?.touched)) {
<div class="flex items-center text-red-600 text-xs mt-1 transition-all">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-3 h-3 mr-1">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
</svg>
<span>กรุณาระบุวันที่</span>
</div>
}
</div>
<div class="quick-log__grid">
<!-- 3. ส่วนหมวดหมู่ -->
<div class="flex flex-col">
<label class="h-full">
<span>หมวดหมู่ <span class="text-red-500">*</span></span>
@if(mode == 'i'){
<select class="w-full h-full px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-blue-50 transition-all bg-white">
<select formControlName="actcat"
class="w-full h-auto px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-blue-50 transition-all bg-white"
[class.border-red-500]="saveFrm.get('actcat')?.invalid && (saveFrm.get('actcat')?.dirty || saveFrm.get('actcat')?.touched)">
<option value="">ไม่เลือก</option>
@for (item of myDropAct.income; track item.dtlcod) {
<option [value]="item.dtlcod">
{{ item.dtlnam }}
</option>
<option [value]="item.dtlcod">{{ item.dtlnam }}</option>
}
</select>
</select>
}@else if(mode == 'e'){
<select class="w-full h-full px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-blue-50 transition-all bg-white">
<select formControlName="actcat"
class="w-full h-auto px-4 py-2 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-100 focus:border-blue-50 transition-all bg-white"
[class.border-red-500]="saveFrm.get('actcat')?.invalid && (saveFrm.get('actcat')?.dirty || saveFrm.get('actcat')?.touched)">
<option value="">ไม่เลือก</option>
@for (item of myDropAct.expense; track item.dtlcod) {
<option [value]="item.dtlcod">
{{ item.dtlnam }}
</option>
<option [value]="item.dtlcod">{{ item.dtlnam }}</option>
}
</select>
</select>
}
</label>
<!-- Validate หมวดหมู่ -->
@if (saveFrm.get('actcat')?.invalid && (saveFrm.get('actcat')?.dirty || saveFrm.get('actcat')?.touched)) {
<div class="flex items-center text-red-600 text-xs mt-1 transition-all">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-3 h-3 mr-1">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
</svg>
<span>กรุณาเลือกหมวดหมู่</span>
</div>
}
</div>
<!-- 4. ส่วนยอดเงิน -->
<div class="flex flex-col">
<label>
<span>ยอดเงิน (฿)</span>
<input type="number" placeholder="0.00" />
<span>ยอดเงิน (฿) <span class="text-red-500">*</span></span>
<input type="number" formControlName="actqty" placeholder="0.00"
[class.border-red-500]="saveFrm.get('actqty')?.invalid && (saveFrm.get('actqty')?.dirty || saveFrm.get('actqty')?.touched)"/>
</label>
</div>
<!-- Validate ยอดเงิน -->
@if (saveFrm.get('actqty')?.invalid && (saveFrm.get('actqty')?.dirty || saveFrm.get('actqty')?.touched)) {
<div class="flex items-center text-red-600 text-xs mt-1 transition-all">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-3 h-3 mr-1">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
</svg>
<span>กรุณาระบุยอดเงิน</span>
</div>
}
</div>
</div>
<!-- 5. ส่วนบันทึกเพิ่มเติม -->
<div class="mb-2">
<label>
<span>บันทึกเพิ่มเติม</span>
<textarea rows="3" placeholder="รายละเอียดการรับ/จ่าย"></textarea>
<span>บันทึกเพิ่มเติม</span>
<textarea rows="3" formControlName="actcmt" placeholder="รายละเอียดการรับ/จ่าย"
[class.border-red-500]="saveFrm.get('actcmt')?.invalid"></textarea>
</label>
<button type="button" class="btn btn--primary">บันทึกรายการ</button>
</form>
</article>
<!-- Validate ความยาวตัวอักษร (ถ้ามี) -->
@if (saveFrm.get('actcmt')?.hasError('maxlength')) {
<div class="flex items-center text-red-600 text-xs mt-1 transition-all">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-3 h-3 mr-1">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
</svg>
<span>พิมพ์ได้สูงสุด 200 ตัวอักษร</span>
</div>
}
</div>
<button type="button" class="btn btn--primary" (click)="onSaveSubmit()">บันทึกรายการ</button>
</div>
</form>
<article class="panel ledger-panel">
<div class="panel__header">
@@ -201,7 +267,7 @@
}
</div>
</article>
</section>
</div>
<section class="dashboard__grid">
<!-- <article class="panel panel--main">
@@ -248,7 +314,7 @@
</div>
</article>
<!-- ตัวเลขซ้อนทับกัน -->
<article class="panel panel--side">
<!-- <article class="panel panel--side">
<div class="panel__header">
<div>
<h2>สรุปสภาพคล่อง</h2>
@@ -265,8 +331,38 @@
</div>
</div>
</div>
</article>
</article> -->
<article class="bg-white border border-gray-200 rounded-2xl p-5 shadow-sm">
<div class="flex justify-between items-center mb-4">
<div>
<h2 class="text-lg font-bold text-gray-800">สรุปสภาพคล่อง</h2>
<p class="text-xs text-gray-400">อัปเดตล่าสุดเมื่อสักครู่</p>
</div>
</div>
<div class="space-y-3">
<div *ngFor="let ratio of quickRatios"
class="flex justify-between items-center p-2 hover:bg-gray-50 rounded-lg transition">
<p class="text-gray-600 text-sm font-medium flex-1 truncate">
{{ ratio.label }}
</p>
<span class="text-base font-semibold" [ngClass]="ratio.colorClass">
<ng-container *ngIf="isNumber(ratio.value); else textVal">
{{ ratio.value | number:'1.2-2' }}
<span *ngIf="ratio.label !== 'อัตรากำไร'" class="text-xs font-normal text-gray-400">บาท</span>
</ng-container>
<ng-template #textVal>
{{ ratio.value }}
</ng-template>
</span>
</div>
</div>
</article>
<!-- <article class="panel alerts-panel">
<div class="panel__header">
<div>