Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions e-commerce-app/src/api/taxApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export const taxApi = createApi({
Authorization: `Bearer ${token}`,
},
};
}
})
})
},
}),
}),
});

export const { useGetAllTaxesQuery } = taxApi;
1 change: 0 additions & 1 deletion e-commerce-app/src/components/ProductCard/ProductCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export const ProductCard: FC<ICardProps> = ({ item }) => {
});
}, [item]);


const imgPath = item.masterData.current.masterVariant.images[0].url;
const imgDescription = item.masterData.current.name.en;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const EmptyProducts: FC = () => {
return (
<Box className={styles.empty__products}>
This is an empty product list. There are no products available!
<img src={empty} alt="home-icon" className={styles.img}/>
<img src={empty} alt="home-icon" className={styles.img} />
</Box>
);
};
13 changes: 13 additions & 0 deletions e-commerce-app/src/components/UserRedirect/UserRedirect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { JSX } from 'react';
import { useAppSelector } from '../../store/hooks';
import { getMyCustomerId } from '../../store/slices/myCustomerSlice';
import { Navigate } from 'react-router-dom';
import LoadingProgress from '../LoadingProgress/LoadingProgress';

const UserRedirect = (): JSX.Element => {
const myCustomerId = useAppSelector(getMyCustomerId);

if (!myCustomerId) return <LoadingProgress />;
return <Navigate to={myCustomerId}/>;
};
export default UserRedirect;
8 changes: 6 additions & 2 deletions e-commerce-app/src/pages/UserPage/UserForm1.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import TextField from '@mui/material/TextField';
import Grid from '@mui/material/Grid';
import { FC } from 'react';
import { FC, useState } from 'react';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import EditIcon from '@mui/icons-material/Edit';
import { useAppSelector } from '../../store/hooks';
import { getMyCustomerFirstName } from '../../store/slices/myCustomerSlice';

export const UserForm1: FC = () => {
const firstName = useAppSelector(getMyCustomerFirstName);
const [changingFirstName, setChangingFirstName] = useState(firstName);
return (
<Box sx={{ width: 450, margin: '0 auto' }}>
<Grid item xs={12} mt={2} sx={{ display: 'flex' }}>
<TextField fullWidth label="First Name" autoComplete="off" />
<TextField fullWidth label="First Name" autoComplete="off" value={changingFirstName} onChange={e => setChangingFirstName(e.target.value)} />
<Button>
<EditIcon />
</Button>
Expand Down
36 changes: 36 additions & 0 deletions e-commerce-app/src/requestsComponents/UserQuery/UserQuery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { JSX, useEffect } from 'react';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import { getAccessToken } from '../../store/slices/userSlice';
import { Outlet } from 'react-router-dom';
import { useGetMyCustomerDetailsMutation } from '../../api/myCustomerApi';
import LoadingProgress from '../../components/LoadingProgress/LoadingProgress';
import { clearMyCustomerData, setMyCustomerData } from '../../store/slices/myCustomerSlice';

const UserQuery = (): JSX.Element => {
const dispatch = useAppDispatch();
const accessToken = useAppSelector(getAccessToken);

const [getMyCustomerDetails, { data, isSuccess, isLoading }] = useGetMyCustomerDetailsMutation();

useEffect(() => {
console.log('Get details ---> ', accessToken);
dispatch(clearMyCustomerData());
if (accessToken) {
getMyCustomerDetails(accessToken);
}
}, []);

useEffect(() => {
if (!isSuccess) return;
if (data) {
console.log(data);
dispatch(setMyCustomerData(data));
}
}, [isSuccess, data]);

if (isLoading) {
return <LoadingProgress/>;
}
return <Outlet/>;
};
export default UserQuery;
10 changes: 6 additions & 4 deletions e-commerce-app/src/routes/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { PrivateRoute } from './PrivateRoute';
import ProductsQuery from '../requestsComponents/ProductsQuery/ProductsQuery';
import CategoriesQuery from '../requestsComponents/CategoriesQuery/CategoriesQuery';
import TokenGuard from '../requestsComponents/TokenGuard/TokenGuard';
import UserQuery from '../requestsComponents/UserQuery/UserQuery';
import UserRedirect from '../components/UserRedirect/UserRedirect';

const router = createHashRouter(
createRoutesFromElements(
Expand All @@ -32,12 +34,12 @@ const router = createHashRouter(
<Route path="/registration" element={<RegistrationPage />} />
<Route path="/basket" element={<BasketPage />} />
<Route element={<PrivateRoute />}>
<Route path="/user" element={<UserPage />}>
{/* TODO : add redirect to the user page */}
<Route path={':customerId'} element={<HomePage />}></Route>
<Route path="/user" element={<UserQuery />}>
<Route index element={<UserRedirect/>}/>
<Route path={':customerId'} element={<UserPage />} />
</Route>
</Route>
<Route element={<CategoriesQuery />} path={'/products'}>
<Route path={'/products'} element={<CategoriesQuery />}>
<Route index element={<ProductsQuery />} />
<Route path=":productId" element={<ProductPage />} />
</Route>
Expand Down
1 change: 0 additions & 1 deletion e-commerce-app/src/routes/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const userLogoutRoutes = {

export const navigationRoutes = {
home: '/',
product: '/product',
products: '/products',
user: '/user',
};
Expand Down
79 changes: 79 additions & 0 deletions e-commerce-app/src/store/slices/myCustomerSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { IMyCustomerBaseResponse } from '../../types/slicesTypes/myCustomerApiSliceTypes';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootStateType } from '../store';

const initialState: IMyCustomerBaseResponse = {
addresses: [],
authenticationMode: 'Password',
billingAddressIds: [],
dateOfBirth: '',
email: '',
firstName: '',
id: '',
isEmailVerified: false,
lastName: '',
password: '',
shippingAddressIds: [],
};

const myCustomerSlice = createSlice({
initialState,
name: 'myCustomerSlice',
reducers: {
clearMyCustomerData: (state) => {
state.addresses.length = 0;
state.authenticationMode = 'Password';
state.billingAddressIds.length = 0;
state.dateOfBirth = '';
state.email = '';
state.firstName = '';
state.id = '';
state.isEmailVerified = false;
state.lastName = '';
state.password = '';
state.shippingAddressIds.length = 0;
if (state.defaultBillingAddressId) {
delete state.defaultBillingAddressId;
}
if (state.defaultShippingAddressId) {
delete state.defaultShippingAddressId;
}
},
setMyCustomerData: (state, action: PayloadAction<IMyCustomerBaseResponse>) => {
state.addresses = action.payload.addresses;
state.authenticationMode = action.payload.authenticationMode;
state.billingAddressIds = action.payload.billingAddressIds;
state.dateOfBirth = action.payload.dateOfBirth;
state.email = action.payload.email;
state.firstName = action.payload.firstName;
state.id = action.payload.id;
state.isEmailVerified = action.payload.isEmailVerified;
state.lastName = action.payload.lastName;
state.password = action.payload.password;
state.shippingAddressIds = action.payload.shippingAddressIds;
if (action.payload.defaultBillingAddressId) {
state.defaultBillingAddressId = action.payload.defaultBillingAddressId;
}
if (action.payload.defaultShippingAddressId) {
state.defaultShippingAddressId = action.payload.defaultShippingAddressId;
}
},
}
});

export const getMyCustomerAddresses = (state: RootStateType) => state.myCustomer.addresses;
export const getMyCustomerBillingAddressIds = (state: RootStateType) => state.myCustomer.billingAddressIds;
export const getMyCustomerDateOfBirth = (state: RootStateType) => state.myCustomer.dateOfBirth;
export const getMyCustomerEmail = (state: RootStateType) => state.myCustomer.email;
export const getMyCustomerFirstName = (state: RootStateType) => state.myCustomer.firstName;
export const getMyCustomerId = (state: RootStateType) => state.myCustomer.id;
export const getMyCustomerIsEmailVerified = (state: RootStateType) => state.myCustomer.isEmailVerified;
export const getMyCustomerLastName = (state: RootStateType) => state.myCustomer.lastName;
export const getMyCustomerPassword = (state: RootStateType) => state.myCustomer.password;
export const getMyCustomerShippingAddressIds = (state: RootStateType) => state.myCustomer.shippingAddressIds;
export const getMyCustomerDefaultBillingAddressId = (state: RootStateType) => state.myCustomer.defaultBillingAddressId;
export const getMyCustomerDefaultShippingAddressId = (state: RootStateType) => state.myCustomer.defaultShippingAddressId;


export const MyCustomerReducer = myCustomerSlice.reducer;
export const { clearMyCustomerData, setMyCustomerData } = myCustomerSlice.actions;
5 changes: 2 additions & 3 deletions e-commerce-app/src/store/slices/taxesSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ export const taxesSlice = createSlice({
state.limit = action.payload.limit;
state.taxes = action.payload.results;
state.fetching = false;
}
}
},
},
});


export const getTaxes = (state: RootStateType) => state.taxes.taxes;
export const TaxesReducer = taxesSlice.reducer;
export const { startLoadingTaxes, setTaxes } = taxesSlice.actions;
3 changes: 2 additions & 1 deletion e-commerce-app/src/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { productProjectionApi } from '../api/productProjectionApi';
import { QueryParamsReducer } from './slices/queryParamsSlice';
import { taxApi } from '../api/taxApi';
import { TaxesReducer } from './slices/taxesSlice';

import { MyCustomerReducer } from './slices/myCustomerSlice';

export const store = configureStore({
reducer: {
Expand All @@ -25,6 +25,7 @@ export const store = configureStore({
products: ProductsReducer,
queryParams: QueryParamsReducer,
taxes: TaxesReducer,
myCustomer: MyCustomerReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({}).concat([
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export interface ISearchProductForm {
query: string
query: string;
}
12 changes: 6 additions & 6 deletions e-commerce-app/src/types/slicesTypes/myCustomerApiSliceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ export interface IMyCustomerLoginRequest {
}

export interface IMyCustomerBaseResponse {
id: string;
addresses: IMyCustomerApiAddressRequest[];
authenticationMode: 'Password' | string;
billingAddressIds: string[];
dateOfBirth: string;
email: string;
firstName: string;
id: string;
isEmailVerified: boolean;
lastName: string;
dateOfBirth: string;
password: string;
addresses: IMyCustomerApiAddressRequest[];
billingAddressIds: string[];
shippingAddressIds: string[];
defaultBillingAddressId?: string;
defaultShippingAddressId?: string;
isEmailVerified: boolean;
authenticationMode: 'Password' | string;
}

export interface IMyCustomerApiSignupRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ export interface ISearchApiResponse extends IProductApiDescriptionResponse {
taxCategory: ICategoryTypeResponse;
}

export interface ISearchProductsResponse extends IBaseGetAllQueryResponse<ISearchApiResponse>{
export interface ISearchProductsResponse extends IBaseGetAllQueryResponse<ISearchApiResponse> {
results: ISearchApiResponse[];
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { ISearchApiResponse, ISearchProductsResponse } from '../types/slicesTypes/productProjectionsApiTypes';
import {
ISearchApiResponse,
ISearchProductsResponse,
} from '../types/slicesTypes/productProjectionsApiTypes';
import {
IGetAllProductsResponse,
IMasterDataProductApiResponse,
IProductApiDescriptionResponse,
IProductApiResponse
IProductApiResponse,
} from '../types/slicesTypes/productsApiTypes';

const makeFromSearchApiProductApiResponses = (el: ISearchApiResponse): IProductApiResponse => {
Expand All @@ -15,7 +18,7 @@ const makeFromSearchApiProductApiResponses = (el: ISearchApiResponse): IProductA
name: el.name,
searchKeywords: el.searchKeywords,
slug: el.slug,
variants: el.variants
variants: el.variants,
};
const masterData: IMasterDataProductApiResponse = {
current: current,
Expand All @@ -28,13 +31,15 @@ const makeFromSearchApiProductApiResponses = (el: ISearchApiResponse): IProductA
key: el.key,
masterData: masterData,
productType: el.productType,
taxCategory: el.taxCategory
taxCategory: el.taxCategory,
};
return newProduct;
};

export const makeProductSliceObjectFromSearchApiRequest = (dataSearch: ISearchProductsResponse): IGetAllProductsResponse => {
const productsArray = dataSearch.results.map(el => makeFromSearchApiProductApiResponses(el));
export const makeProductSliceObjectFromSearchApiRequest = (
dataSearch: ISearchProductsResponse,
): IGetAllProductsResponse => {
const productsArray = dataSearch.results.map((el) => makeFromSearchApiProductApiResponses(el));
const pushingObject: IGetAllProductsResponse = {
limit: dataSearch.limit,
offset: dataSearch.offset,
Expand Down