cda-redux
Redux/RTK Query React SPA combining a user area (login/register/home) and a Star Wars module (listing, pagination, filtering) with authentication and session handling. The project demonstrates RTK Query for external API consumption and client-side cache management.
π― Context and goals
- Structure a modern frontend application around Redux Toolkit and asynchronous API flows.
- Implement an authentication baseline with token storage, current-user retrieval, and access protection.
- Deliver browsing/search features with derived state and pagination.
π οΈ Deliverables
π§© Design
- The stack includes React, Vite, Redux Toolkit, RTK Query, and React Router v6, with persistence and debug middleware. Source: cda-redux/vite-project/package.json
{
"scripts": {
"dev": "vite ./",
"build": "vite build ./",
"serve": "vite preview ./"
},
"dependencies": {
"@reduxjs/toolkit": "^1.6.2",
"react": "^17.0.0",
"react-redux": "^7.2.6",
"react-router-dom": "^6.0.2",
"redux": "^4.1.2",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^1.0.0",
"vite": "^2.6.4"
}
}
- The store configures three RTK Query APIs (
peopleApi,authApi,usersManagerApi) plus an auth slice, with concatenated middleware. Source: cda-redux/vite-project/src/js/store/store.js
export const store = configureStore({
reducer: {
[peopleApi.reducerPath]: peopleApi.reducer,
[authApi.reducerPath]: authApi.reducer,
[usersManagerApi.reducerPath]: usersManagerApi.reducer,
auth,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(
usersManagerApi.middleware,
authApi.middleware,
peopleApi.middleware,
logger
),
});
π» Development
- Backend :
Auth integration applies prepared-header logic (
Bearer+x-xsrf-token) to secure authenticated API requests. Source: cda-redux/vite-project/src/js/services/authService.js
const baseQuery = fetchBaseQuery({
baseUrl: "<REDACTED_URL>",
prepareHeaders: (headers, { getState }) => {
const accessToken = getState().auth.accessToken;
const xsrfToken = getState().auth.xsrfToken;
if (accessToken && xsrfToken) {
headers.set("authorization", `Bearer ${accessToken}`);
headers.set("x-xsrf-token", xsrfToken);
}
return headers;
},
});
The RTK Query layer encapsulates authentication/session endpoints (/auth/login, /auth/me, /auth/token, /users/).
Source: cda-redux/vite-project/src/js/services/authService.js
export const authApi = createApi({
reducerPath: "authApi",
baseQuery: baseQuery,
keepUnusedDataFor: false,
endpoints: (builder) => ({
login: builder.mutation({ query: (userInfo) => loginRequest("/auth/login", userInfo) }),
fetchCurrentUser: builder.query({ query: () => authMeRequest("/auth/me") }),
authToken: builder.mutation({ query: (emailToken) => authTokenRequest("/auth/token", emailToken) }),
register: builder.mutation({
query: (body) => ({ url: "/users/", method: "POST", body }),
}),
}),
});
- Frontend : Routing is split between public pages and protected business areas, with redirects and nested routes. Source: cda-redux/vite-project/src/js/App.jsx
<Routes>
<Route path="/register" element={<Register />} />
<Route path="/login" element={<Login />} />
<Route path="/" element={<Navigate replace to="/home" />} />
<Route path="/home" element={<HomePage />}>
<Route path="users" element={<ListUsers />}></Route>
<Route path="research-user" element={<p>Rechercher des utilisateurs</p>}></Route>
<Route path="profil" element={<InfoProfil />}></Route>
</Route>
<Route path="/starwars/people" element={<PeopleStarWars />} />
<Route path="/starwars/people/:peopleId" element={<PeopleStarWarsDetails />} />
</Routes>
The useIsAuth hook restores credentials from local storage, syncs Redux state, and triggers current-user fetch.
Source: cda-redux/vite-project/src/js/hooks/useIsAuth.js
useEffect(() => {
const accessToken = getLocalStorageItem("accessToken");
const xsrfToken = getLocalStorageItem("xsrfToken");
if (accessToken && xsrfToken) {
dispatch(setCredentials({ accessToken, xsrfToken }));
} else {
dispatch(setIsInitialized());
}
const refreshToken = getLocalStorageItem("refreshToken");
const email = getLocalStorageItem("email");
if (email && refreshToken) {
async () => {
const result = authToken({ email, refreshToken });
console.log("result auth/token", result);
};
}
}, []);
The Star Wars page implements text search, gender filtering, and pagination on top of SWAPI through RTK Query. Source: cda-redux/vite-project/src/js/pages/PeopleStarWars.jsx
const [page, setPage] = useState(1);
const { data: peopleStarwars, isFetching } = useFetchAllPeopleQuery(page);
const [searchTerm, setSearchTerm] = useState("");
const [activeCategory, setActiveCategory] = useState("");
<ul className="people-list">
{peopleStarwars?.results
?.filter((val) => {
if (searchTerm == "") return val;
if (val.name.toLowerCase().includes(searchTerm.toLowerCase())) return val;
})
.map(({ name, height, mass, gender }, index) =>
!activeCategory || activeCategory === gender ? (
<div key={name}><PeopleItem index={index} name={name} height={height} mass={mass} gender={gender} /></div>
) : null
)}
</ul>
ποΈ DevOps & Quality
- The repository includes a GitLab CI pipeline for frontend build and
distartifact publication, followed by automated deployment stage. Source: cda-redux/.gitlab-ci.yml
image: node:16
stages:
- build
- deploy
build_parcel_master:
stage: build
script:
- cd ./vite-project/
- npm install
- npm run build
artifacts:
expire_in: 20 mins
paths:
- ./vite-project/dist
π Results
- Based on the analyzed Git history, the work spans 2021-11-08 -> 2026-02-14, with 24 commits across 3 contributors. The project delivers a structured SPA with API authentication, Redux-based token/session handling, and list/search navigation modules on external data. RTK Query usage standardizes asynchronous data flows and reduces network-call boilerplate. The technical benefit is a maintainable frontend foundation for multi-API use cases with centralized global state.
π§ Technical environment
- Frontend: React 17, React Router 6, Vite.
- State/API: Redux Toolkit, RTK Query (
authApi,peopleApi,usersManagerApi), React Redux, Redux Logger. - Data sources: user/auth API (redacted URL), SWAPI (
people). - Session: local token persistence + initialization through
useIsAuth. - DevOps: GitLab CI (build, artifacts, deployment).