diff --git a/api/package-lock.json b/api/package-lock.json
index ea3bdf6..8c9fb86 100644
--- a/api/package-lock.json
+++ b/api/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "expense-control-api",
- "version": "1.0.0",
+ "version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "expense-control-api",
- "version": "1.0.0",
+ "version": "0.0.1",
"dependencies": {
"bcryptjs": "^3.0.2",
"cors": "^2.8.5",
diff --git a/web/package-lock.json b/web/package-lock.json
index f71b36a..9b240c8 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "expense-control-web",
- "version": "0.0.0",
+ "version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "expense-control-web",
- "version": "0.0.0",
+ "version": "0.0.1",
"dependencies": {
"@angular/common": "^21.2.7",
"@angular/compiler": "^21.2.7",
diff --git a/web/src/app/app.html b/web/src/app/app.html
new file mode 100644
index 0000000..e194f53
--- /dev/null
+++ b/web/src/app/app.html
@@ -0,0 +1,2 @@
+
| {{ ui.t('admin.database') }} | {{ systemInfo()!.database }} |
| Upload dir | {{ systemInfo()!.uploadDir }} |
| {{ ui.t('admin.registration') }} | {{ systemInfo()!.registrationEnabled ? ui.t('common.active') : ui.t('common.blocked') }} |
| SMTP | {{ systemInfo()!.smtpConfigured ? ui.t('admin.smtpReady') : ui.t('admin.smtpNotReady') }} |
| API base | {{ systemInfo()!.sources.apiBasePath }} |
| {{ ui.t('table.date') }} | {{ systemInfo()!.checkedAt | date:'yyyy-MM-dd HH:mm:ss' }} |
| {{ ui.t('admin.userLabel') }} | {{ ui.t('admin.role') }} | {{ ui.t('admin.status') }} | {{ ui.t('admin.integrationsAccess') }} | {{ ui.t('admin.date') }} | |
|---|---|---|---|---|---|
|
+ {{ user.fullName }}
+ {{ user.email }}
+ |
+ {{ user.role }} | ++ + {{ user.isActive ? ui.t('common.active') : ui.t('common.blocked') }} + + | +{{ user.integrationsEnabled ? ui.t('common.active') : ui.t('common.blocked') }} | +{{ user.createdAt | date:'short' }} | +
+
+
+
+
+
+
+ |
+
| + + | +|||||
| {{ ui.t('admin.noUsers') }} | |||||
| {{ ui.t('admin.database') }} | {{ systemInfo()!.database }} |
| Upload dir | {{ systemInfo()!.uploadDir }} |
| {{ ui.t('admin.registration') }} | {{ systemInfo()!.registrationEnabled ? ui.t('common.active') : ui.t('common.blocked') }} |
| SMTP | {{ systemInfo()!.smtpConfigured ? ui.t('admin.smtpReady') : ui.t('admin.smtpNotReady') }} |
| API base | {{ systemInfo()!.sources.apiBasePath }} |
| {{ ui.t('table.date') }} | {{ systemInfo()!.checkedAt | date:'yyyy-MM-dd HH:mm:ss' }} |
| {{ ui.t('admin.userLabel') }} | {{ ui.t('admin.role') }} | {{ ui.t('admin.status') }} | {{ ui.t('admin.integrationsAccess') }} | {{ ui.t('admin.date') }} | |
|---|---|---|---|---|---|
|
- {{ user.fullName }}
- {{ user.email }}
- |
- {{ user.role }} | -- - {{ user.isActive ? ui.t('common.active') : ui.t('common.blocked') }} - - | -{{ user.integrationsEnabled ? ui.t('common.active') : ui.t('common.blocked') }} | -{{ user.createdAt | date:'short' }} | -
-
-
-
-
-
-
- |
-
| - - | -|||||
| {{ ui.t('admin.noUsers') }} | |||||
| {{ ui.t('budget.name') }} | {{ ui.t('table.category') }} | {{ ui.t('budget.usage') }} | {{ ui.t('table.amount') }} | |
|---|---|---|---|---|
{{ item.name || item.category?.name || ui.t('budget.overall') }} |
+ {{ item.category?.name || ui.t('budget.overall') }} | +{{ item.usagePercent }}% | +{{ item.spent | currency:'PLN':'symbol':'1.2-2' }} / {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
+ + |
| {{ ui.t('common.noData') }} | ||||
| {{ ui.t('budget.name') }} | {{ ui.t('table.category') }} | {{ ui.t('budget.usage') }} | {{ ui.t('table.amount') }} | |
|---|---|---|---|---|
{{ item.name || item.category?.name || ui.t('budget.overall') }} |
- {{ item.category?.name || ui.t('budget.overall') }} | -{{ item.usagePercent }}% | -{{ item.spent | currency:'PLN':'symbol':'1.2-2' }} / {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
- - |
| {{ ui.t('common.noData') }} | ||||
| {{ ui.t('expenses.field.status') }} | {{ ui.t('table.count') }} |
|---|---|
| {{ ui.t('status.' + item.status.toLowerCase()) }} | {{ item.count }} |
| {{ ui.t('common.noData') }} | |
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ item.title }} | {{ item.nextRunDate | date:'yyyy-MM-dd' }} | {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('expenses.field.status') }} | {{ ui.t('table.count') }} |
|---|---|
| {{ ui.t('status.' + item.status.toLowerCase()) }} | {{ item.count }} |
| {{ ui.t('common.noData') }} | |
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ item.title }} | {{ item.nextRunDate | date:'yyyy-MM-dd' }} | {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('categories.name') }} | {{ ui.t('categories.color') }} | {{ ui.t('categories.type') }} | |
|---|---|---|---|
| {{ item.name }} | +{{ item.color }} | +{{ item.isSystem ? ui.t('categories.system') : ui.t('categories.custom') }} | +
+
+
+ @if (!item.isSystem) {
+
+ }
+
+ |
+
| {{ ui.t('common.noCategories') }} | |||
| {{ ui.t('categories.name') }} | {{ ui.t('categories.color') }} | {{ ui.t('categories.type') }} | |
|---|---|---|---|
| {{ item.name }} | -{{ item.color }} | -{{ item.isSystem ? ui.t('categories.system') : ui.t('categories.custom') }} | -
-
-
- @if (!item.isSystem) {
-
- }
-
- |
-
| {{ ui.t('common.noCategories') }} | |||
| {{ ui.t('table.title') }} | {{ ui.t('table.category') }} | {{ ui.t('expenses.field.status') }} | {{ ui.t('table.amount') }} |
|---|---|---|---|
|
+ {{ item.title }}
+ {{ item.merchant || ui.t('expenses.noMerchant') }}
+ |
+ {{ item.category.name }} | +{{ ui.t('status.' + item.status.toLowerCase()) }} | +{{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | +
| {{ ui.t('common.noExpenses') }} | |||
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ item.title }} | {{ item.nextRunDate | date:'yyyy-MM-dd' }} | {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('table.title') }} | {{ ui.t('table.category') }} | {{ ui.t('expenses.field.status') }} | {{ ui.t('table.amount') }} |
|---|---|---|---|
|
- {{ item.title }}
- {{ item.merchant || ui.t('expenses.noMerchant') }}
- |
- {{ item.category.name }} | -{{ ui.t('status.' + item.status.toLowerCase()) }} | -{{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | -
| {{ ui.t('common.noExpenses') }} | |||
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ item.title }} | {{ item.nextRunDate | date:'yyyy-MM-dd' }} | {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | ||
| + + | ++ | + | + | + | + | {{ ui.t('table.actions') }} | +
|---|---|---|---|---|---|---|
| + | {{ item.expenseDate | date:'yyyy-MM-dd' }} | +
+
+ {{ item.title }}
+ @if (item.possibleDuplicate || item.duplicateStatus) {
+ {{ duplicateLabel(item) }}
+ }
+ @if (item.recurringSourceId) {
+ {{ ui.t('recurring.badge') }}
+ }
+
+ {{ item.merchant || ui.t('expenses.noMerchant') }}
+ @if (item.tags.length) { @for (tag of item.tags; track tag) { #{{ tag }} } }
+ @if (customFieldEntries(item).length) { @for (field of customFieldEntries(item); track field[0]) { {{ field[0] }}: {{ field[1] }} } }
+ @if (item.proofs.length) { @for (proof of item.proofs; track proof.id) { } }
+ |
+ {{ item.category.name }} | +
+
+ {{ ui.t('status.' + item.status.toLowerCase()) }}
+
+
+ |
+ {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | +
+
+ {{ ui.t('action.view') }}
+ @if (item.possibleDuplicate && item.duplicateStatus !== 'CONFIRMED') {
+
+ }
+ @if (item.possibleDuplicate && item.duplicateStatus !== 'DISMISSED') {
+
+ }
+ @if (item.duplicateStatus === 'DISMISSED' || item.duplicateStatus === 'CONFIRMED') {
+
+ }
+
+
+
+ |
+
| {{ ui.t('expenses.noItems') }} | ||||||
| - - | -- | - | - | - | - | {{ ui.t('table.actions') }} | -
|---|---|---|---|---|---|---|
| - | {{ item.expenseDate | date:'yyyy-MM-dd' }} | -
-
- {{ item.title }}
- @if (item.possibleDuplicate || item.duplicateStatus) {
- {{ duplicateLabel(item) }}
- }
- @if (item.recurringSourceId) {
- {{ ui.t('recurring.badge') }}
- }
-
- {{ item.merchant || ui.t('expenses.noMerchant') }}
- @if (item.tags.length) { @for (tag of item.tags; track tag) { #{{ tag }} } }
- @if (customFieldEntries(item).length) { @for (field of customFieldEntries(item); track field[0]) { {{ field[0] }}: {{ field[1] }} } }
- @if (item.proofs.length) { @for (proof of item.proofs; track proof.id) { } }
- |
- {{ item.category.name }} | -
-
- {{ ui.t('status.' + item.status.toLowerCase()) }}
-
-
- |
- {{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | -
-
- {{ ui.t('action.view') }}
- @if (item.possibleDuplicate && item.duplicateStatus !== 'CONFIRMED') {
-
- }
- @if (item.possibleDuplicate && item.duplicateStatus !== 'DISMISSED') {
-
- }
- @if (item.duplicateStatus === 'DISMISSED' || item.duplicateStatus === 'CONFIRMED') {
-
- }
-
-
-
- |
-
| {{ ui.t('expenses.noItems') }} | ||||||
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ itemTitle(item) }} | +{{ itemDate(item) }} | +{{ itemAmount(item) | currency:'PLN':'symbol':'1.2-2' }} | +
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('table.title') }} | {{ ui.t('table.date') }} | {{ ui.t('table.amount') }} |
|---|---|---|
| {{ itemTitle(item) }} | -{{ itemDate(item) }} | -{{ itemAmount(item) | currency:'PLN':'symbol':'1.2-2' }} | -
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('merchant.name') }} | {{ ui.t('merchant.type') }} | {{ ui.t('admin.status') }} | {{ ui.t('merchant.notes') }} | |
|---|---|---|---|---|
| {{ item.name }} | +{{ labelKind(item.kind) }} | +{{ item.isActive ? ui.t('common.active') : ui.t('common.hidden') }} | +{{ item.notes || ui.t('common.none') }} | +
+
+
+
+
+ |
+
| {{ ui.t('merchant.noneSaved') }} | ||||
| {{ ui.t('merchant.name') }} | {{ ui.t('merchant.type') }} | {{ ui.t('admin.status') }} | {{ ui.t('merchant.notes') }} | |
|---|---|---|---|---|
| {{ item.name }} | -{{ labelKind(item.kind) }} | -{{ item.isActive ? ui.t('common.active') : ui.t('common.hidden') }} | -{{ item.notes || ui.t('common.none') }} | -
-
-
-
-
- |
-
| {{ ui.t('merchant.noneSaved') }} | ||||
| {{ ui.t('table.title') }} | {{ ui.t('recurring.frequency') }} | {{ ui.t('recurring.nextRunDate') }} | {{ ui.t('table.amount') }} | |
|---|---|---|---|---|
|
+ {{ item.title }}
+ {{ item.category.name }} · {{ item.merchant || ui.t('expenses.noMerchant') }}
+ {{ ui.t('recurring.generatedCount') }}: {{ item.generatedCount }} · {{ ui.t('recurring.endDate') }}: {{ item.endDate || ui.t('common.none') }}
+ @for (tag of item.tags; track tag) { #{{ tag }} }
+ |
+ {{ ui.t('recurring.' + item.frequency.toLowerCase()) }} | +{{ item.nextRunDate | date:'yyyy-MM-dd' }} | +{{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | ++ |
| {{ ui.t('common.noData') }} | ||||
| {{ ui.t('table.title') }} | {{ ui.t('recurring.frequency') }} | {{ ui.t('recurring.nextRunDate') }} | {{ ui.t('table.amount') }} | |
|---|---|---|---|---|
|
- {{ item.title }}
- {{ item.category.name }} · {{ item.merchant || ui.t('expenses.noMerchant') }}
- {{ ui.t('recurring.generatedCount') }}: {{ item.generatedCount }} · {{ ui.t('recurring.endDate') }}: {{ item.endDate || ui.t('common.none') }}
- @for (tag of item.tags; track tag) { #{{ tag }} }
- |
- {{ ui.t('recurring.' + item.frequency.toLowerCase()) }} | -{{ item.nextRunDate | date:'yyyy-MM-dd' }} | -{{ item.amount | currency:'PLN':'symbol':'1.2-2' }} | -- |
| {{ ui.t('common.noData') }} | ||||
| {{ ui.t('table.category') }} | {{ ui.t('table.amount') }} | {{ ui.t('table.count') }} |
|---|---|---|
| {{ row.categoryName }} | {{ row.total | currency:'PLN':'symbol':'1.2-2' }} | {{ row.count }} |
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('expenses.field.tags') }} | {{ ui.t('table.amount') }} |
|---|---|
| #{{ row.tag }} | {{ row.total | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | |
| {{ ui.t('table.category') }} | {{ ui.t('table.amount') }} | {{ ui.t('table.count') }} |
|---|---|---|
| {{ row.categoryName }} | {{ row.total | currency:'PLN':'symbol':'1.2-2' }} | {{ row.count }} |
| {{ ui.t('common.noData') }} | ||
| {{ ui.t('expenses.field.tags') }} | {{ ui.t('table.amount') }} |
|---|---|
| #{{ row.tag }} | {{ row.total | currency:'PLN':'symbol':'1.2-2' }} |
| {{ ui.t('common.noData') }} | |