Skip to content

Commit

Permalink
Merge pull request #28 from khanh-devos/get-new-ebike
Browse files Browse the repository at this point in the history
8. [5pts] Add new ebike feature #41
  • Loading branch information
khanh-devos authored Nov 10, 2023
2 parents 3eef4c1 + f6c8da2 commit c8e534d
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { resetMessage } from './redux/auth/authSlice';
import { fetchLocations } from './redux/location/locationSlice';
import Message from './Message';
import { resetReservationMessage } from './redux/reservation/reservationSlice';
import EbikeForm from './Components/EbikeForm';

function App() {
const dispatch = useDispatch();
Expand Down Expand Up @@ -47,6 +48,7 @@ function App() {
<Route path="/myreservations" element={<MyReservations />} />
<Route path="/login" element={<Loginpage />} />
<Route path="/signup" element={<Signup />} />
<Route path="/addEbike" element={<EbikeForm />} />

{
!isLogined
Expand Down
90 changes: 90 additions & 0 deletions src/Components/EbikeForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// YourComponent.js
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { postEbike } from '../redux/ebike/addingNewbike';

function EbikeForm() {
const dispatch = useDispatch();

const [ebikeData, setEbikeData] = useState({
name: '',
model: '',
image: '',
description: '',
price: 0,
city: '',
weight: 0,
});

const handleChange = (e) => {
setEbikeData({ ...ebikeData, [e.target.name]: e.target.value });
};

const handleSubmit = (e) => {
e.preventDefault();
dispatch(postEbike(ebikeData));
setEbikeData({
name: '',
model: '',
image: '',
description: '',
price: 0,
city: '',
weight: 0,
});
};

return (
<div className="mainclass">
<form onSubmit={handleSubmit} className="getInput">
<h1>Add your new ebike</h1>
<div className="">
<input required name="name" value={ebikeData.name} onChange={handleChange} label="set your name" type="text" placeholder="add your name" />
</div>
<div className="">
<select type="text" required name="model" value={ebikeData.model} onChange={handleChange} placeholder="Model">
<option selected hidden value="Pedego-bike">Select your ebike</option>
<option value="Rad Power Bikes">Rad Power Bikes</option>
<option value="Specialized Turbo">Rad Power Bikes</option>
<option value="Haibike">Haibike</option>
<option value="Gazelle">Gazelle</option>
<option value="Trek Electric Bikes">Trek Electric Bikes</option>
<option value="Raleigh Electric">Raleigh Electric</option>
<option value="Juiced Bikes">Juiced Bikes</option>
<option value="Ariel Rider">Ariel Rider</option>
<option value="Riese & Mülle">Riese & Mülle</option>
</select>
</div>
<div className="">
<input type="text" required name="image" value={ebikeData.image} onChange={handleChange} placeholder="Image URL" />
</div>
<div className="">
<textarea name="description" required value={ebikeData.description} onChange={handleChange} placeholder="Description" />
</div>
<div className="">
<input type="number" required name="price" value={ebikeData.price} onChange={handleChange} placeholder="Price" />
</div>
<div className="">
<select type="text" required name="city" value={ebikeData.city} onChange={handleChange} placeholder="City">
<option selected hidden value="Pedego-bike">Select your city</option>
<option value="Kigali">Kigali</option>
<option value="Zambia">Zambia</option>
<option value="Ghana">Ghana</option>
<option value="Tanzania">Tanzania</option>
<option value="India">India</option>
<option value="Congo(drc)">Congo(drc)</option>
<option value="Nigeria">Nigeria</option>
<option value="Zimbabwe">Zimbabwe</option>
<option value="Uganda">Uganda</option>
</select>
</div>
<div className="">
<input type="number" required name="weight" value={ebikeData.weight} onChange={handleChange} placeholder="Weight" />
</div>
<button type="submit">Submit</button>
</form>
</div>
);
}

export default EbikeForm;
4 changes: 2 additions & 2 deletions src/Components/NavigationPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ function NavigationPanel() {
<img className=" w-1/2 h-1/5 block mx-auto" src={logo} alt="car logo" />
<div className="flex flex-col w-full h-4/5 absolute md:left-0 bottom-0 md:pl-3 justify-between">
<ul className="mt-10">
<li className=""><NavLink onClick={removeNavPanel} className="p-2 hover:bg-[#97BF11] hover:text-white font-[900] text-xs my-2 block" to="/ebikes">E-BIKE</NavLink></li>
<li className=""><NavLink onClick={removeNavPanel} className="p-2 hover:bg-[#3f4235] hover:text-white font-[900] text-xs my-2 block" to="/ebikes">E-BIKE</NavLink></li>

<li className=""><NavLink onClick={removeNavPanel} className="p-2 hover:bg-[#97BF11] hover:text-white font-[900] text-xs my-2 block" to="/">ADD BIKE</NavLink></li>
<li className=""><NavLink onClick={removeNavPanel} className="p-2 hover:bg-[#97BF11] hover:text-white font-[900] text-xs my-2 block" to="/addEbike">ADD BIKE</NavLink></li>
<li className=""><NavLink onClick={removeNavPanel} className="p-2 hover:bg-[#97BF11] hover:text-white font-[900] text-xs my-2 block" to="/">REMOVE BIKE</NavLink></li>

{
Expand Down
129 changes: 129 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,132 @@ body {
opacity: 0.8;
text-transform: uppercase;
}

.mainclass {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}

.getInput {
background-color: #f3f3f4;
border: 1px solid #464684;
color: #000;
padding: 10px 25px;
border-radius: 25px;
font-size: 16px;
width: 40%;
height: 84%;
transition: all 1.3s ease-in-out;
}

.getInput input {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin-top: 20px;
}

.getInput textarea {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin-top: 20px;
}

.getInput select {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin-top: 20px;
background-color: #989a923d;
}

.getInput button {
width: 50%;
border: 2px;
outline: black;
font-size: 16px;
border-radius: 5px;
margin-top: 20px;
background-color: #97bf0f;
color: #fff;
padding: 10px 25px;
cursor: pointer;
transition: all 1.3s ease-in-out;
}

.getInput button:hover {
background-color: #f3f3f4;
color: #000;
border: 1px solid #464684;
}

.getInput h1 {
font-size: 30px;
width: 100%;
margin-bottom: 10px;
}

@media only screen and (max-width: 600px) {
.getInput {
width: 90%;
height: 93%;
margin: 0 auto;
}

.getInput input {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin-top: 5px;
}

/* here some style and responsive */
.getInput textarea {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin-top: 20px;
}

.getInput select {
width: 100%;
height: 100%;
border: 2px;
outline: black;
font-size: 16px;
padding: 10px;
border-radius: 5px;
margin: 20px 20px 20px 0;
background-color: #989a923d;
}

.getInput h1 {
font-size: 20px;
width: 100%;
margin-bottom: 10px;
}
}
58 changes: 58 additions & 0 deletions src/redux/ebike/addingNewbike.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// ebikeSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

const EBIKE_URL = 'http://localhost:3100/api/v1/ebikes';

const initialState = {
ebikes: {},
ebikeLoading: false,
ebikeError: false,
ebikeSuccess: false,
ebikeMessage: '',
};

export const postEbike = createAsyncThunk(
'ebike/postEbike',
async (ebikeData, thunkAPI) => {
try {
const { token } = JSON.parse(localStorage.getItem('ebikeData'));
const res = await axios.post(EBIKE_URL, ebikeData, {
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${token}`,
},
});
return res.data;
} catch (err) {
return thunkAPI.rejectWithValue('add new ebike failed');
}
},
);

const ebikeSliceadding = createSlice({
name: 'ebikeSliceadding',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(postEbike.pending, (state) => ({
...state,
ebikeLoading: true,
}))
.addCase(postEbike.fulfilled, (state, { payload }) => ({
...state,
ebikeLoading: false,
ebikes: payload,
ebikeSuccess: true,
}))
.addCase(postEbike.rejected, (state, { payload }) => ({
...state,
ebikeLoading: false,
ebikeError: true,
ebikeMessage: payload,
}));
},
});

export default ebikeSliceadding.reducer;
2 changes: 2 additions & 0 deletions src/redux/store.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import authSlice from './auth/authSlice';

import locationSlice from './location/locationSlice';
import reservationSlice from './reservation/reservationSlice';
import ebikeSliceadding from './ebike/addingNewbike';

const store = configureStore({
reducer: {
locationSlice,
authSlice,
ebikeSlice,
reservationSlice,
ebikeSliceadding,
},
});

Expand Down

0 comments on commit c8e534d

Please sign in to comment.