Skip to content

Commit a624f6b

Browse files
authored
feat: request other users to duel (#29)
1 parent 61f7c7f commit a624f6b

File tree

19 files changed

+1439
-175
lines changed

19 files changed

+1439
-175
lines changed

src/entities/duel-configuration/api/duelConfigurationApi.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ interface UpdateDuelConfigurationArgs {
1313

1414
export const duelConfigurationApiSlice = apiSlice.injectEndpoints({
1515
endpoints: (builder) => ({
16+
getDuelConfigurations: builder.query<DuelConfiguration[], void>({
17+
query: () => "/configurations",
18+
providesTags: (result) =>
19+
result
20+
? [
21+
...result.map(({ id }) => ({ type: "DuelConfiguration" as const, id })),
22+
{ type: "DuelConfiguration", id: "LIST" },
23+
]
24+
: [{ type: "DuelConfiguration", id: "LIST" }],
25+
}),
1626
createDuelConfiguration: builder.mutation<
1727
DuelConfiguration,
1828
CreateDuelConfigurationRequest
@@ -53,6 +63,7 @@ export const duelConfigurationApiSlice = apiSlice.injectEndpoints({
5363
});
5464

5565
export const {
66+
useGetDuelConfigurationsQuery,
5667
useCreateDuelConfigurationMutation,
5768
useUpdateDuelConfigurationMutation,
5869
useDeleteDuelConfigurationMutation,

src/entities/duel-configuration/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export {
22
useCreateDuelConfigurationMutation,
33
useDeleteDuelConfigurationMutation,
4+
useGetDuelConfigurationsQuery,
45
useGetDuelConfigurationQuery,
56
useUpdateDuelConfigurationMutation,
67
} from "./api/duelConfigurationApi";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { apiSlice } from "shared/api";
2+
3+
import type { DuelRequest } from "../model/types";
4+
5+
export const duelRequestApiSlice = apiSlice.injectEndpoints({
6+
endpoints: (builder) => ({
7+
getDuelRequests: builder.query<DuelRequest[], void>({
8+
query: () => "/duels/requests",
9+
providesTags: (result) =>
10+
result
11+
? [
12+
...result.map((request) => ({
13+
type: "DuelRequest" as const,
14+
id: request.opponent_nickname ?? request.created_at,
15+
})),
16+
{ type: "DuelRequest", id: "LIST" },
17+
]
18+
: [{ type: "DuelRequest", id: "LIST" }],
19+
}),
20+
denyDuelRequest: builder.mutation<void, string>({
21+
query: (nickname) => ({
22+
url: `/duels/requests/${encodeURIComponent(nickname)}/deny`,
23+
method: "POST",
24+
}),
25+
invalidatesTags: [{ type: "DuelRequest", id: "LIST" }],
26+
}),
27+
}),
28+
});
29+
30+
export const { useGetDuelRequestsQuery, useDenyDuelRequestMutation } = duelRequestApiSlice;

src/entities/duel-request/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { useDenyDuelRequestMutation, useGetDuelRequestsQuery } from "./api/duelRequestApi";
2+
export type { DuelRequest } from "./model/types";
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface DuelRequest {
2+
opponent_nickname: string | null;
3+
created_at: string;
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { DuelConfigurationManager } from "./ui/DuelConfigurationManager";
2+
export { DuelConfigurationPicker } from "./ui/DuelConfigurationPicker";

src/features/duel-configuration/ui/DuelConfigurationManager.module.scss

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@
1010
gap: 1.25em;
1111
}
1212

13+
.cardFlat {
14+
width: 100%;
15+
padding: 0;
16+
border-radius: 0;
17+
background-color: transparent;
18+
box-shadow: none;
19+
gap: 0.9em;
20+
}
21+
22+
.cardFlat .configList {
23+
gap: 0.5em;
24+
}
25+
1326
.listHeader {
1427
display: flex;
1528
align-items: flex-start;
@@ -18,12 +31,38 @@
1831
flex-wrap: wrap;
1932
}
2033

34+
.listHeaderStack {
35+
flex-direction: column;
36+
align-items: center;
37+
}
38+
39+
.listHeaderActions {
40+
display: flex;
41+
flex-direction: column;
42+
align-items: flex-end;
43+
gap: 0.5em;
44+
}
45+
46+
.listHeaderActionsCentered {
47+
align-items: center;
48+
}
49+
50+
.listHeaderActionsLeft {
51+
display: flex;
52+
justify-content: flex-start;
53+
}
54+
2155
.listHeaderText {
2256
display: flex;
2357
flex-direction: column;
2458
gap: 0.35em;
2559
}
2660

61+
.listHeaderCentered {
62+
align-items: center;
63+
text-align: center;
64+
}
65+
2766
.plusIcon {
2867
font-size: 1.1rem;
2968
line-height: 1;
@@ -218,6 +257,31 @@
218257
background-color: var(--card-secondary);
219258
}
220259

260+
.configItemSelectable {
261+
width: 100%;
262+
border: 1px solid transparent;
263+
text-align: left;
264+
cursor: pointer;
265+
font: inherit;
266+
color: inherit;
267+
transition:
268+
border-color 0.2s ease,
269+
background-color 0.2s ease;
270+
}
271+
272+
.configItemSelectable:hover {
273+
background-color: color-mix(in srgb, var(--card-secondary) 90%, white);
274+
}
275+
276+
.configItemSelected {
277+
border-color: var(--accent-primary);
278+
background-color: color-mix(in srgb, var(--card-secondary) 80%, white);
279+
}
280+
281+
.defaultConfigItem {
282+
margin-bottom: 0.25em;
283+
}
284+
221285
.configSummary {
222286
display: flex;
223287
flex-direction: column;
@@ -253,6 +317,18 @@
253317
font-size: 0.8rem;
254318
}
255319

320+
.deleteHint {
321+
font-size: 0.9rem;
322+
color: var(--text-secondary);
323+
}
324+
325+
.deleteActions {
326+
display: flex;
327+
justify-content: flex-end;
328+
gap: 0.75em;
329+
margin-top: 1em;
330+
}
331+
256332
.mutedLabel {
257333
cursor: default;
258334
color: var(--text-secondary);

0 commit comments

Comments
 (0)