Skip to content

Commit b6bc97b

Browse files
Add available remarks
1 parent 510d9ce commit b6bc97b

File tree

7 files changed

+100
-13
lines changed

7 files changed

+100
-13
lines changed

client/src/apis/record.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@ export async function deleteRecord(id: number) {
3838

3939
return response.data;
4040
}
41+
42+
export async function getRemarks(categoryId: number): Promise<string[]> {
43+
const url = `v1/records/category/${categoryId}/remarks`;
44+
const response = await Axios.get(url);
45+
46+
return response.data;
47+
}

client/src/components/record/RecordModal.tsx

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22
import CustomModal from '../Custom/CustomModal';
33
import {
44
ICategory,
@@ -11,7 +11,12 @@ import {
1111
import Calculator from '../calculator/Calculator';
1212
import { evaluate } from 'mathjs';
1313
import CustomTextField from '../Custom/CustomTextField';
14-
import { createRecord, deleteRecord, updateRecord } from '../../apis/record';
14+
import {
15+
createRecord,
16+
deleteRecord,
17+
getRemarks,
18+
updateRecord,
19+
} from '../../apis/record';
1520
import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
1621
import { AxiosError } from 'axios';
1722
import { toast } from 'react-toastify';
@@ -73,8 +78,16 @@ const RecordModal = ({
7378
profile(userId!),
7479
);
7580

81+
const { data: remarks } = useQuery<string[]>(
82+
['remarks', selectedCategory?.id],
83+
() => getRemarks(selectedCategory?.id!),
84+
);
85+
7686
const { wallets } = useRecord();
7787

88+
const datePickerRef = useRef<any>(null);
89+
const textInputRef = useRef<HTMLDivElement>(null);
90+
7891
const updateCalc = (key: string) => {
7992
if (key === '=') {
8093
return setValue((prev) => {
@@ -267,6 +280,7 @@ const RecordModal = ({
267280
type: 'Once' | 'Continue',
268281
) => {
269282
event.preventDefault();
283+
270284
try {
271285
if (!editRecord.price) {
272286
return toast('Please input the expense/income', { type: 'warning' });
@@ -301,6 +315,12 @@ const RecordModal = ({
301315

302316
useEffect(() => {
303317
const keyListener = (event: KeyboardEvent) => {
318+
if (
319+
textInputRef.current?.contains(document.activeElement) ||
320+
datePickerRef.current.input.contains(document.activeElement)
321+
) {
322+
return;
323+
}
304324
const reg = /\d|\/|\*|-|\+|\./g;
305325

306326
if (event.key === 'Backspace') {
@@ -447,6 +467,7 @@ const RecordModal = ({
447467
</div>
448468
</div>
449469
<DatePicker
470+
ref={datePickerRef}
450471
onChange={(e) => {
451472
if (e) {
452473
setEditRecord((prev) => {
@@ -480,7 +501,7 @@ const RecordModal = ({
480501
}}
481502
/>
482503
</div>
483-
<div className="py-2">
504+
<div className="py-2" ref={textInputRef}>
484505
<CustomTextField
485506
type={'text'}
486507
name="Remarks"
@@ -494,6 +515,23 @@ const RecordModal = ({
494515
});
495516
}}
496517
/>
518+
<div className="text-sm pt-2 flex flex-wrap gap-2">
519+
{remarks?.map((remark) => (
520+
<span
521+
className="bg-info-100 rounded-lg p-1 cursor-pointer hover:bg-info-200"
522+
onClick={() => {
523+
setEditRecord((prev) => {
524+
return {
525+
...prev,
526+
remarks: remark,
527+
};
528+
});
529+
}}
530+
>
531+
{remark}
532+
</span>
533+
))}
534+
</div>
497535
</div>
498536

499537
{/* Submit button and choose continue or close */}

client/src/pages/Records.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,10 @@ const Records = (props: Props) => {
156156
>
157157
<IconSelector name={record.category.icon} />
158158
</div>
159-
160-
<span>{record.category.name}</span>
161-
<span>{record.remarks}</span>
159+
<span className="flex items-baseline gap-2">
160+
<span>{record.category.name}</span>
161+
<span className="text-sm">{record.remarks}</span>
162+
</span>
162163
</div>
163164

164165
<span>

src/categories/categories.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class CategoriesService {
3636
}
3737

3838
async findOne(id: number) {
39-
return await this.categoryRepository.find({
39+
return await this.categoryRepository.findOne({
4040
where: {
4141
id,
4242
},

src/records/records.controller.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
2020
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
2121
import { UsersService } from '../users/users.service';
2222
import { WalletsService } from '../wallets/wallets.service';
23+
import { CategoriesService } from '../categories/categories.service';
2324

2425
@ApiTags('Record')
2526
@ApiBearerAuth()
@@ -30,7 +31,8 @@ export class RecordsController {
3031
constructor(
3132
private readonly recordsService: RecordsService,
3233
private readonly usersService: UsersService,
33-
private readonly walletService: WalletsService,
34+
private readonly walletsService: WalletsService,
35+
private readonly categoriesService: CategoriesService,
3436
) {}
3537

3638
@Post()
@@ -46,7 +48,7 @@ export class RecordsController {
4648

4749
@Get('/wallet/:id')
4850
async findAll(@Param('id') id: number) {
49-
const wallet = await this.walletService.findOne(id);
51+
const wallet = await this.walletsService.findOne(id);
5052

5153
if (!wallet) {
5254
throw new BadRequestException('Wallet does not exist');
@@ -56,7 +58,7 @@ export class RecordsController {
5658
}
5759

5860
@Get(':id')
59-
findOne(@Param('id') id: string) {
61+
findOne(@Param('id') id: number) {
6062
return this.recordsService.findOne(+id);
6163
}
6264

@@ -75,7 +77,28 @@ export class RecordsController {
7577
}
7678

7779
@Delete(':id')
78-
remove(@Param('id') id: string) {
79-
return this.recordsService.remove(+id);
80+
async remove(@Param('id') id: number) {
81+
return await this.recordsService.remove(+id);
82+
}
83+
84+
@Get('/category/:categoryId/remarks')
85+
async getRemarks(@Param('categoryId') categoryId: number) {
86+
// Get all the remarks of that category
87+
const category = await this.categoriesService.findOne(categoryId);
88+
89+
if (!category) {
90+
throw new BadRequestException('The category does not exist');
91+
}
92+
93+
const records = await this.recordsService.getRemarks(category);
94+
return records.reduce((remarks: string[], record) => {
95+
if (
96+
record.remarks &&
97+
!remarks.find((remark) => remark === record.remarks)
98+
) {
99+
remarks.push(record.remarks);
100+
}
101+
return remarks;
102+
}, []);
80103
}
81104
}

src/records/records.module.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@ import { TypeOrmModule } from '@nestjs/typeorm';
55
import { Record } from './entities/record.entity';
66
import { UsersModule } from '../users/users.module';
77
import { WalletsModule } from '../wallets/wallets.module';
8+
import { CategoriesModule } from '../categories/categories.module';
89

910
@Module({
10-
imports: [TypeOrmModule.forFeature([Record]), UsersModule, WalletsModule],
11+
imports: [
12+
TypeOrmModule.forFeature([Record]),
13+
UsersModule,
14+
WalletsModule,
15+
CategoriesModule,
16+
],
1117
controllers: [RecordsController],
1218
providers: [RecordsService],
1319
})

src/records/records.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { InjectRepository } from '@nestjs/typeorm';
55
import { Record } from './entities/record.entity';
66
import { Repository } from 'typeorm';
77
import { Wallet } from '../wallets/entities/wallet.entity';
8+
import { Category } from '../categories/entities/category.entity';
89

910
@Injectable()
1011
export class RecordsService {
@@ -53,4 +54,15 @@ export class RecordsService {
5354
async remove(id: number) {
5455
return await this.recordRepository.softDelete(id);
5556
}
57+
58+
async getRemarks(category: Category) {
59+
return await this.recordRepository.find({
60+
relations: { category: true },
61+
where: {
62+
category: {
63+
id: category.id,
64+
},
65+
},
66+
});
67+
}
5668
}

0 commit comments

Comments
 (0)