Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

address saving functionality #100

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions backend/changeLog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
addressModel: Built the address model to store the addresses for customers, sellers and admins together based on their user ID.
server.js: Changed the server.js file to add the routes for Address creation and fetch
addressRouter: Created this file to perform all the logic of address posting and fetching with the correct routes. (Post on Postman, Fetch on App)
21 changes: 21 additions & 0 deletions backend/models/addressModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import mongoose from 'mongoose';

const addressSchema = new mongoose.Schema(
{
name: { type: String, required: true },
phone: { type: Number, required: true, unique: true },
pincode: { type: Number, required: true},
addressLine: { type: String, required: true},
landmark: { type: String, required: true},
city: { type: String, required: true },
state: { type: String, required: true },
addressType: { type: String},
user: {type : mongoose.Schema.Types.ObjectId, ref: 'User', required: true}
},
{
timestamps: true,
}
);
const Address = mongoose.model('Address', addressSchema);
export default Address;

182 changes: 182 additions & 0 deletions backend/routers/addressRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import bcrypt from 'bcryptjs';
import data from '../data.js';
import Address from '../models/addressModel.js';
import { generateToken, isAdmin, isAuth } from '../utils.js';

const addressRouter = express.Router();

addressRouter.get(
'/',
expressAsyncHandler(async (req, res) => {
console.log("address")
const address = await Address.find()
res.send({address});
})
);

addressRouter.post(
'/',
isAuth,
expressAsyncHandler(async (req, res) => {
console.log("Address req ", req)
const address = new Address({
name: req.body.name,
phone: req.body.phone,
pincode: req.body.pincode,
addressLine: req.body.addressLine,
landmark: req.body.landmark,
city: req.body.city,
state: req.body.state,
addressType: req.body.addressType,
user: req.body.user
});
const createAddress = await address.save();
res
.status(201)
.send({ message: 'New Address Created', address: createAddress });
})
);

// userRouter.get(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to remove commented code (dead code).

// '/seed',
// expressAsyncHandler(async (req, res) => {
// // await User.remove({});
// const createdUsers = await User.insertMany(data.users);
// res.send({ createdUsers });
// })
// );

// userRouter.post(
// '/signin',
// expressAsyncHandler(async (req, res) => {
// const user = await User.findOne({ email: req.body.email });
// if (user) {
// if (bcrypt.compareSync(req.body.password, user.password)) {
// res.send({
// _id: user._id,
// name: user.name,
// email: user.email,
// isAdmin: user.isAdmin,
// isSeller: user.isSeller,
// token: generateToken(user),
// });
// return;
// }
// }
// res.status(401).send({ message: 'Invalid email or password' });
// })
// );

// userRouter.post(
// '/register',
// expressAsyncHandler(async (req, res) => {
// const user = new User({
// name: req.body.name,
// email: req.body.email,
// password: bcrypt.hashSync(req.body.password, 8),
// });
// const createdUser = await user.save();
// res.send({
// _id: createdUser._id,
// name: createdUser.name,
// email: createdUser.email,
// isAdmin: createdUser.isAdmin,
// isSeller: user.isSeller,
// token: generateToken(createdUser),
// });
// })
// );

// userRouter.get(
// '/:id',
// expressAsyncHandler(async (req, res) => {
// const user = await User.findById(req.params.id);
// if (user) {
// res.send(user);
// } else {
// res.status(404).send({ message: 'User Not Found' });
// }
// })
// );
// userRouter.put(
// '/profile',
// isAuth,
// expressAsyncHandler(async (req, res) => {
// const user = await User.findById(req.user._id);
// if (user) {
// user.name = req.body.name || user.name;
// user.email = req.body.email || user.email;
// if (user.isSeller) {
// user.seller.name = req.body.sellerName || user.seller.name;
// user.seller.logo = req.body.sellerLogo || user.seller.logo;
// user.seller.description =
// req.body.sellerDescription || user.seller.description;
// }
// if (req.body.password) {
// user.password = bcrypt.hashSync(req.body.password, 8);
// }
// const updatedUser = await user.save();
// res.send({
// _id: updatedUser._id,
// name: updatedUser.name,
// email: updatedUser.email,
// isAdmin: updatedUser.isAdmin,
// isSeller: user.isSeller,
// token: generateToken(updatedUser),
// });
// }
// })
// );

// userRouter.get(
// '/',
// isAuth,
// isAdmin,
// expressAsyncHandler(async (req, res) => {
// const users = await User.find({});
// res.send(users);
// })
// );

// userRouter.delete(
// '/:id',
// isAuth,
// isAdmin,
// expressAsyncHandler(async (req, res) => {
// const user = await User.findById(req.params.id);
// if (user) {
// if (user.email === '[email protected]') {
// res.status(400).send({ message: 'Can Not Delete Admin User' });
// return;
// }
// const deleteUser = await user.remove();
// res.send({ message: 'User Deleted', user: deleteUser });
// } else {
// res.status(404).send({ message: 'User Not Found' });
// }
// })
// );

// userRouter.put(
// '/:id',
// isAuth,
// isAdmin,
// expressAsyncHandler(async (req, res) => {
// const user = await User.findById(req.params.id);
// if (user) {
// user.name = req.body.name || user.name;
// user.email = req.body.email || user.email;
// user.isSeller = Boolean(req.body.isSeller);
// user.isAdmin = Boolean(req.body.isAdmin);
// // user.isAdmin = req.body.isAdmin || user.isAdmin;
// const updatedUser = await user.save();
// res.send({ message: 'User Updated', user: updatedUser });
// } else {
// res.status(404).send({ message: 'User Not Found' });
// }
// })
// );

export default addressRouter;
1 change: 1 addition & 0 deletions backend/routers/orderRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ orderRouter.post(
'/',
isAuth,
expressAsyncHandler(async (req, res) => {
console.log("Order req ", req)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove logs.

if (req.body.orderItems.length === 0) {
res.status(400).send({ message: 'Cart is empty' });
} else {
Expand Down
2 changes: 2 additions & 0 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import productRouter from './routers/productRouter.js';
import userRouter from './routers/userRouter.js';
import orderRouter from './routers/orderRouter.js';
import uploadRouter from './routers/uploadRouter.js';
import addressRouter from './routers/addressRouter.js';

dotenv.config();

Expand All @@ -24,6 +25,7 @@ app.use('/api/uploads', uploadRouter);
app.use('/api/users', userRouter);
app.use('/api/products', productRouter);
app.use('/api/orders', orderRouter);
app.use('/api/address', addressRouter);
app.get('/api/config/paypal', (req, res) => {
res.send(process.env.PAYPAL_CLIENT_ID || 'sb');
});
Expand Down
6 changes: 6 additions & 0 deletions frontend/changeLog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
addressReducers: Created addressReducers file (support file)
addressConstants: Created addressConstants file (support file)
AddressActions: Created AddressActions file (support file)
AddressScreen: Created AddressScreen file to let the users add and see their saved addresses.
App.js: Redesigned the navbar to match that of Amazon. Introduced the address feature.
store.js: (support file)
45 changes: 32 additions & 13 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { signout } from './actions/userActions';
import AdminRoute from './components/AdminRoute';
import PrivateRoute from './components/PrivateRoute';
import CartScreen from './screens/CartScreen';
import ReturnScreen from './screens/ReturnScreen';
import HomeScreen from './screens/HomeScreen';
import AddressScreen from './screens/AddressScreen';
import OrderHistoryScreen from './screens/OrderHistoryScreen';
import OrderScreen from './screens/OrderScreen';
import PaymentMethodScreen from './screens/PaymentMethodScreen';
Expand Down Expand Up @@ -55,18 +57,25 @@ function App() {
return (
<BrowserRouter>
<div className="grid-container">
<header className="row">
<div className="rowHeader">
<header className="rowHeaderInside">
<div>
<button
{
<button
type="button"
className="open-sidebar"
onClick={() => setSidebarIsOpen(true)}
>
<i className="fa fa-bars"></i>
</button>
<Link className="brand" to="/">
amazona
}
<Link className="brand" to="/" style={{fontSize:'2.8rem'}}>amazona
</Link>

<Link className="brand" to="/address" style={{fontSize:'1.4rem'}}>
<i class="fa fa-map-marker" aria-hidden="true" style={{fontSize:'3rem'}}></i> <b>Your Addresses</b>
</Link>

</div>
<div>
<Route
Expand All @@ -76,16 +85,10 @@ function App() {
></Route>
</div>
<div>
<Link to="/cart">
Cart
{cartItems.length > 0 && (
<span className="badge">{cartItems.length}</span>
)}
</Link>
{userInfo ? (
<div className="dropdown">
<Link to="#">
{userInfo.name} <i className="fa fa-caret-down"></i>{' '}
<Link to="#" style={{padding:'30px'}}>Hello {userInfo.name} <i className="fa fa-caret-down"></i>
<br></br><span style={{fontSize:'1.3rem'}}><b>Accounts & Lists</b></span>
</Link>
<ul className="dropdown-content">
<li>
Expand Down Expand Up @@ -143,12 +146,25 @@ function App() {
</ul>
</div>
)}
<Link to="/cart">
<span className="returns">Returns</span> <span className="orders"><b>& Orders</b></span>
{cartItems.length > 0 && (
<span className="badge">{cartItems.length}</span>
)}
</Link>
<Link to="/cart">
<i class="fa fa-shopping-cart" style={{fontSize:'3rem'}} aria-hidden="true"></i> Cart
{cartItems.length > 0 && (
<span className="badge">{cartItems.length}</span>
)}
</Link>
</div>
</header>
</div>
<aside className={sidebarIsOpen ? 'open' : ''}>
<ul className="categories">
<li>
<strong>Categories</strong>
<h1><strong>Hello customer </strong></h1>
<button
onClick={() => setSidebarIsOpen(false)}
className="close-sidebar"
Expand Down Expand Up @@ -177,7 +193,9 @@ function App() {
</aside>
<main>
<Route path="/seller/:id" component={SellerScreen}></Route>
<Route path="/address" component={AddressScreen}></Route>
<Route path="/cart/:id?" component={CartScreen}></Route>
<Route path="/return/:id?" component={ReturnScreen}></Route>
<Route path="/product/:id" component={ProductScreen} exact></Route>
<Route
path="/product/:id/edit"
Expand Down Expand Up @@ -259,6 +277,7 @@ function App() {
<div>All right reserved</div>{' '}
</footer>
</div>

</BrowserRouter>
);
}
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/actions/addressActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Axios from 'axios';
import {
ADDRESS_CREATE_REQUEST,
ADDRESS_CREATE_SUCCESS,
ADDRESS_CREATE_FAIL,
ADDRESS_LIST_REQUEST,
ADDRESS_LIST_SUCCESS,
ADDRESS_LIST_FAIL
} from '../constants/addressConstants';

export const listAddresses = () => async (dispatch) => {
dispatch({ type: ADDRESS_LIST_REQUEST });
try {
const { data } = await Axios.get('/api/address', {
});
console.log(data)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove logs.

dispatch({ type: ADDRESS_LIST_SUCCESS, payload: data });
} catch (error) {
dispatch({ type: ADDRESS_LIST_FAIL, payload: error.message });
}
};
1 change: 1 addition & 0 deletions frontend/src/actions/userActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const signin = (email, password) => async (dispatch) => {
dispatch({ type: USER_SIGNIN_REQUEST, payload: { email, password } });
try {
const { data } = await Axios.post('/api/users/signin', { email, password });
console.log("TOKEN ", data)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove logs.

dispatch({ type: USER_SIGNIN_SUCCESS, payload: data });
localStorage.setItem('userInfo', JSON.stringify(data));
} catch (error) {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/SearchBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export default function SearchBox(props) {
};
return (
<form className="search" onSubmit={submitHandler}>
<div className="row">
<div className="rowSearch">
<input
className="rowSearch"
type="text"
name="q"
id="q"
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/constants/addressConstants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const ADDRESS_CREATE_REQUEST = 'ADDRESS_CREATE_REQUEST';
export const ADDRESS_CREATE_SUCCESS = 'ADDRESS_CREATE_SUCCESS';
export const ADDRESS_CREATE_FAIL = 'ADDRESS_CREATE_FAIL';

export const ADDRESS_LIST_REQUEST = 'ADDRESS_LIST_REQUEST';
export const ADDRESS_LIST_SUCCESS = 'ADDRESS_LIST_SUCCESS';
export const ADDRESS_LIST_FAIL = 'ADDRESS_LIST_FAIL';
export const ADDRESS_DETAILS_RESET = 'ADDRESS_DETAILS_RESET';
Loading