formatting
This commit is contained in:
@@ -1,184 +1,224 @@
|
||||
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
|
||||
import axios from "../../axios";
|
||||
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
|
||||
import axios from '../../axios';
|
||||
|
||||
// Типы данных
|
||||
export interface Submit {
|
||||
id?: number;
|
||||
missionId: number;
|
||||
language: string;
|
||||
languageVersion: string;
|
||||
sourceCode: string;
|
||||
contestId: number | null;
|
||||
id?: number;
|
||||
missionId: number;
|
||||
language: string;
|
||||
languageVersion: string;
|
||||
sourceCode: string;
|
||||
contestId: number | null;
|
||||
}
|
||||
|
||||
export interface Solution {
|
||||
id: number;
|
||||
missionId: number;
|
||||
language: string;
|
||||
languageVersion: string;
|
||||
sourceCode: string;
|
||||
status: string;
|
||||
time: string;
|
||||
testerState: string;
|
||||
testerErrorCode: string;
|
||||
testerMessage: string;
|
||||
currentTest: number;
|
||||
amountOfTests: number;
|
||||
id: number;
|
||||
missionId: number;
|
||||
language: string;
|
||||
languageVersion: string;
|
||||
sourceCode: string;
|
||||
status: string;
|
||||
time: string;
|
||||
testerState: string;
|
||||
testerErrorCode: string;
|
||||
testerMessage: string;
|
||||
currentTest: number;
|
||||
amountOfTests: number;
|
||||
}
|
||||
|
||||
export interface MissionSubmit {
|
||||
id: number;
|
||||
userId: number;
|
||||
solution: Solution;
|
||||
contestId: number | null;
|
||||
contestName: string | null;
|
||||
sourceType: string;
|
||||
id: number;
|
||||
userId: number;
|
||||
solution: Solution;
|
||||
contestId: number | null;
|
||||
contestName: string | null;
|
||||
sourceType: string;
|
||||
}
|
||||
|
||||
interface SubmitState {
|
||||
submits: Submit[];
|
||||
submitsById: Record<number, MissionSubmit[]>; // ✅ добавлено
|
||||
currentSubmit?: Submit;
|
||||
status: "idle" | "loading" | "successful" | "failed";
|
||||
error: string | null;
|
||||
submits: Submit[];
|
||||
submitsById: Record<number, MissionSubmit[]>; // ✅ добавлено
|
||||
currentSubmit?: Submit;
|
||||
status: 'idle' | 'loading' | 'successful' | 'failed';
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
// Начальное состояние
|
||||
const initialState: SubmitState = {
|
||||
submits: [],
|
||||
submitsById: {}, // ✅ инициализация
|
||||
currentSubmit: undefined,
|
||||
status: "idle",
|
||||
error: null,
|
||||
submits: [],
|
||||
submitsById: {}, // ✅ инициализация
|
||||
currentSubmit: undefined,
|
||||
status: 'idle',
|
||||
error: null,
|
||||
};
|
||||
|
||||
// AsyncThunk: Отправка решения
|
||||
export const submitMission = createAsyncThunk(
|
||||
"submit/submitMission",
|
||||
async (submitData: Submit, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.post("/submits", submitData);
|
||||
return response.data;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err.response?.data?.message || "Submit failed");
|
||||
}
|
||||
}
|
||||
'submit/submitMission',
|
||||
async (submitData: Submit, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.post('/submits', submitData);
|
||||
return response.data;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(
|
||||
err.response?.data?.message || 'Submit failed',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// AsyncThunk: Получить все свои отправки
|
||||
export const fetchMySubmits = createAsyncThunk(
|
||||
"submit/fetchMySubmits",
|
||||
async (_, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get("/submits/my");
|
||||
return response.data as Submit[];
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err.response?.data?.message || "Failed to fetch submits");
|
||||
}
|
||||
}
|
||||
'submit/fetchMySubmits',
|
||||
async (_, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get('/submits/my');
|
||||
return response.data as Submit[];
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(
|
||||
err.response?.data?.message || 'Failed to fetch submits',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// AsyncThunk: Получить конкретную отправку по ID
|
||||
export const fetchSubmitById = createAsyncThunk(
|
||||
"submit/fetchSubmitById",
|
||||
async (id: number, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get(`/submits/${id}`);
|
||||
return response.data as Submit;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err.response?.data?.message || "Failed to fetch submit");
|
||||
}
|
||||
}
|
||||
'submit/fetchSubmitById',
|
||||
async (id: number, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get(`/submits/${id}`);
|
||||
return response.data as Submit;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(
|
||||
err.response?.data?.message || 'Failed to fetch submit',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// ✅ AsyncThunk: Получить отправки для конкретной миссии (новая структура)
|
||||
export const fetchMySubmitsByMission = createAsyncThunk(
|
||||
"submit/fetchMySubmitsByMission",
|
||||
async (missionId: number, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get(`/submits/my/mission/${missionId}`);
|
||||
return { missionId, data: response.data as MissionSubmit[] };
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err.response?.data?.message || "Failed to fetch mission submits");
|
||||
}
|
||||
}
|
||||
'submit/fetchMySubmitsByMission',
|
||||
async (missionId: number, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`/submits/my/mission/${missionId}`,
|
||||
);
|
||||
return { missionId, data: response.data as MissionSubmit[] };
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(
|
||||
err.response?.data?.message ||
|
||||
'Failed to fetch mission submits',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Slice
|
||||
const submitSlice = createSlice({
|
||||
name: "submit",
|
||||
initialState,
|
||||
reducers: {
|
||||
clearCurrentSubmit: (state) => {
|
||||
state.currentSubmit = undefined;
|
||||
state.status = "idle";
|
||||
state.error = null;
|
||||
name: 'submit',
|
||||
initialState,
|
||||
reducers: {
|
||||
clearCurrentSubmit: (state) => {
|
||||
state.currentSubmit = undefined;
|
||||
state.status = 'idle';
|
||||
state.error = null;
|
||||
},
|
||||
clearSubmitsByMission: (state, action: PayloadAction<number>) => {
|
||||
delete state.submitsById[action.payload];
|
||||
},
|
||||
},
|
||||
clearSubmitsByMission: (state, action: PayloadAction<number>) => {
|
||||
delete state.submitsById[action.payload];
|
||||
extraReducers: (builder) => {
|
||||
// Отправка решения
|
||||
builder.addCase(submitMission.pending, (state) => {
|
||||
state.status = 'loading';
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(
|
||||
submitMission.fulfilled,
|
||||
(state, action: PayloadAction<Submit>) => {
|
||||
state.status = 'successful';
|
||||
state.submits.push(action.payload);
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
submitMission.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.payload;
|
||||
},
|
||||
);
|
||||
|
||||
// Получить все свои отправки
|
||||
builder.addCase(fetchMySubmits.pending, (state) => {
|
||||
state.status = 'loading';
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(
|
||||
fetchMySubmits.fulfilled,
|
||||
(state, action: PayloadAction<Submit[]>) => {
|
||||
state.status = 'successful';
|
||||
state.submits = action.payload;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchMySubmits.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.payload;
|
||||
},
|
||||
);
|
||||
|
||||
// Получить отправку по ID
|
||||
builder.addCase(fetchSubmitById.pending, (state) => {
|
||||
state.status = 'loading';
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(
|
||||
fetchSubmitById.fulfilled,
|
||||
(state, action: PayloadAction<Submit>) => {
|
||||
state.status = 'successful';
|
||||
state.currentSubmit = action.payload;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchSubmitById.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.payload;
|
||||
},
|
||||
);
|
||||
|
||||
// ✅ Получить отправки по миссии
|
||||
builder.addCase(fetchMySubmitsByMission.pending, (state) => {
|
||||
state.status = 'loading';
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(
|
||||
fetchMySubmitsByMission.fulfilled,
|
||||
(
|
||||
state,
|
||||
action: PayloadAction<{
|
||||
missionId: number;
|
||||
data: MissionSubmit[];
|
||||
}>,
|
||||
) => {
|
||||
state.status = 'successful';
|
||||
state.submitsById[action.payload.missionId] =
|
||||
action.payload.data;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchMySubmitsByMission.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.payload;
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
// Отправка решения
|
||||
builder.addCase(submitMission.pending, (state) => {
|
||||
state.status = "loading";
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(submitMission.fulfilled, (state, action: PayloadAction<Submit>) => {
|
||||
state.status = "successful";
|
||||
state.submits.push(action.payload);
|
||||
});
|
||||
builder.addCase(submitMission.rejected, (state, action: PayloadAction<any>) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
|
||||
// Получить все свои отправки
|
||||
builder.addCase(fetchMySubmits.pending, (state) => {
|
||||
state.status = "loading";
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(fetchMySubmits.fulfilled, (state, action: PayloadAction<Submit[]>) => {
|
||||
state.status = "successful";
|
||||
state.submits = action.payload;
|
||||
});
|
||||
builder.addCase(fetchMySubmits.rejected, (state, action: PayloadAction<any>) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
|
||||
// Получить отправку по ID
|
||||
builder.addCase(fetchSubmitById.pending, (state) => {
|
||||
state.status = "loading";
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(fetchSubmitById.fulfilled, (state, action: PayloadAction<Submit>) => {
|
||||
state.status = "successful";
|
||||
state.currentSubmit = action.payload;
|
||||
});
|
||||
builder.addCase(fetchSubmitById.rejected, (state, action: PayloadAction<any>) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
|
||||
// ✅ Получить отправки по миссии
|
||||
builder.addCase(fetchMySubmitsByMission.pending, (state) => {
|
||||
state.status = "loading";
|
||||
state.error = null;
|
||||
});
|
||||
builder.addCase(
|
||||
fetchMySubmitsByMission.fulfilled,
|
||||
(state, action: PayloadAction<{ missionId: number; data: MissionSubmit[] }>) => {
|
||||
state.status = "successful";
|
||||
state.submitsById[action.payload.missionId] = action.payload.data;
|
||||
}
|
||||
);
|
||||
builder.addCase(fetchMySubmitsByMission.rejected, (state, action: PayloadAction<any>) => {
|
||||
state.status = "failed";
|
||||
state.error = action.payload;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const { clearCurrentSubmit, clearSubmitsByMission } = submitSlice.actions;
|
||||
export const { clearCurrentSubmit, clearSubmitsByMission } =
|
||||
submitSlice.actions;
|
||||
export const submitReducer = submitSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user