Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add: slice for object
  • Loading branch information
htnghia1423 committed Apr 29, 2025
commit 99ce95601f5beb16aa56a13ce323e236431a46ab
133 changes: 133 additions & 0 deletions src/features/gifts/giftSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { PayloadAction, createAsyncThunk, createSlice } from '@reduxjs/toolkit';

import * as giftService from '@/features/gifts/giftService';
import { CreateGiftDTO, GiftIdea, GiftState } from '@/features/gifts/types';

const initialState: GiftState = {
gifts: [],
loading: false,
error: null,
};

export const fetchGifts = createAsyncThunk(
'gifts/fetchGifts',
async (_, { rejectWithValue }) => {
try {
return await giftService.fetchGifts();
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

export const addGift = createAsyncThunk(
'gifts/addGift',
async (gift: CreateGiftDTO, { rejectWithValue }) => {
try {
return await giftService.addGift(gift);
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

export const deleteGift = createAsyncThunk(
'gifts/deleteGift',
async (id: string, { rejectWithValue }) => {
try {
await giftService.deleteGift(id);
return id;
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

// Thêm action updateGift
export const updateGift = createAsyncThunk(
'gifts/updateGift',
async (gift: Partial<GiftIdea>, { rejectWithValue }) => {
try {
return await giftService.updateGift(gift);
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

const giftSlice = createSlice({
name: 'gifts',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
// Fetch Gifts
.addCase(fetchGifts.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(
fetchGifts.fulfilled,
(state, action: PayloadAction<GiftIdea[]>) => {
state.loading = false;
state.gifts = action.payload;
},
)
.addCase(fetchGifts.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
})

// Add Gift
.addCase(addGift.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(addGift.fulfilled, (state, action: PayloadAction<GiftIdea>) => {
state.loading = false;
state.gifts.push(action.payload);
})
.addCase(addGift.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
})

// Delete Gift
.addCase(deleteGift.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(deleteGift.fulfilled, (state, action: PayloadAction<string>) => {
state.loading = false;
state.gifts = state.gifts.filter((gift) => gift.id !== action.payload);
})
.addCase(deleteGift.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
})

// Update Gift
.addCase(updateGift.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(
updateGift.fulfilled,
(state, action: PayloadAction<GiftIdea>) => {
state.loading = false;
const index = state.gifts.findIndex(
(gift) => gift.id === action.payload.id,
);
if (index !== -1) {
state.gifts[index] = action.payload;
}
},
)
.addCase(updateGift.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
});
},
});

export default giftSlice.reducer;
88 changes: 88 additions & 0 deletions src/features/recipients/recipientSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { PayloadAction, createAsyncThunk, createSlice } from '@reduxjs/toolkit';

import * as recipientService from '@/features/recipients/recipientService';
import {
CreateRecipientDTO,
Recipient,
RecipientState,
} from '@/features/recipients/types';

const initialState: RecipientState = {
recipients: [],
loading: false,
error: null,
};

export const fetchRecipients = createAsyncThunk(
'recipients/fetchRecipients',
async (_, { rejectWithValue }) => {
try {
return await recipientService.fetchRecipients();
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

export const addRecipient = createAsyncThunk(
'recipients/addRecipient',
async (recipient: CreateRecipientDTO, { rejectWithValue }) => {
try {
return await recipientService.addRecipient(recipient);
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

export const deleteRecipient = createAsyncThunk(
'recipients/deleteRecipient',
async (id: string, { rejectWithValue }) => {
try {
await recipientService.deleteRecipient(id);
return id;
} catch (error) {
return rejectWithValue((error as Error).message);
}
},
);

const recipientSlice = createSlice({
name: 'recipients',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchRecipients.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(
fetchRecipients.fulfilled,
(state, action: PayloadAction<Recipient[]>) => {
state.loading = false;
state.recipients = action.payload;
},
)
.addCase(fetchRecipients.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
})
.addCase(
addRecipient.fulfilled,
(state, action: PayloadAction<Recipient>) => {
state.recipients.push(action.payload);
},
)
.addCase(
deleteRecipient.fulfilled,
(state, action: PayloadAction<string>) => {
state.recipients = state.recipients.filter(
(recipient) => recipient.id !== action.payload,
);
},
);
},
});

export default recipientSlice.reducer;