Action
· 629 B · Text
Raw
export const SELECT_GAME = 'SELECT_GAME';
export const SELECT_DATE = 'SELECT_DATE';
export const SELECT_SLOT = 'SELECT_SLOT';
export const BOOK_SLOT = 'BOOK_SLOT';
export const SAVE_DETAILS = 'SAVE_DETAILS';
export const selectGame = (game) => ({
type: SELECT_GAME,
payload: game,
});
export const selectDate = (date) => ({
type: SELECT_DATE,
payload: date,
});
export const selectSlot = (slot) => ({
type: SELECT_SLOT,
payload: slot,
});
export const bookSlot = (booking) => ({
type: BOOK_SLOT,
payload: booking,
});
export const saveDetails = (details) => ({
type: SAVE_DETAILS,
payload: details,
});
1 | |
2 | export const SELECT_GAME = 'SELECT_GAME'; |
3 | export const SELECT_DATE = 'SELECT_DATE'; |
4 | export const SELECT_SLOT = 'SELECT_SLOT'; |
5 | export const BOOK_SLOT = 'BOOK_SLOT'; |
6 | export const SAVE_DETAILS = 'SAVE_DETAILS'; |
7 | |
8 | export const selectGame = (game) => ({ |
9 | type: SELECT_GAME, |
10 | payload: game, |
11 | }); |
12 | |
13 | export const selectDate = (date) => ({ |
14 | type: SELECT_DATE, |
15 | payload: date, |
16 | }); |
17 | |
18 | export const selectSlot = (slot) => ({ |
19 | type: SELECT_SLOT, |
20 | payload: slot, |
21 | }); |
22 | |
23 | export const bookSlot = (booking) => ({ |
24 | type: BOOK_SLOT, |
25 | payload: booking, |
26 | }); |
27 | |
28 | export const saveDetails = (details) => ({ |
29 | type: SAVE_DETAILS, |
30 | payload: details, |
31 | }); |
32 |
App.js
· 695 B · JavaScript
Raw
import "./App.css";
import Games from "./pages/home";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import React, { Component } from "react";
import Booking from "./pages/book";
import Search_Booking from "./pages/search_booking";
class App extends Component {
state = {};
render() {
return (
<div>
<Router>
<div>
<Switch>
<Route exact path="/" component={Games} />
<Route exact path="/booking" component={Booking} />
<Route exact path="/search" component={Search_Booking} />
</Switch>
</div>
</Router>
</div>
);
}
}
export default App;
1 | import "./App.css"; |
2 | import Games from "./pages/home"; |
3 | import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; |
4 | import React, { Component } from "react"; |
5 | import Booking from "./pages/book"; |
6 | import Search_Booking from "./pages/search_booking"; |
7 | class App extends Component { |
8 | state = {}; |
9 | render() { |
10 | return ( |
11 | <div> |
12 | <Router> |
13 | <div> |
14 | <Switch> |
15 | <Route exact path="/" component={Games} /> |
16 | <Route exact path="/booking" component={Booking} /> |
17 | <Route exact path="/search" component={Search_Booking} /> |
18 | </Switch> |
19 | </div> |
20 | </Router> |
21 | </div> |
22 | ); |
23 | } |
24 | } |
25 | |
26 | export default App; |
27 |
Book
· 2.9 KiB · Text
Raw
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { bookSlot, saveDetails, selectSlot } from './action';
import { useNavigate } from 'react-router-dom';
const slots = ['10AM', '11AM', '12PM', '1PM', '2PM', '3PM', '4PM'];
const Book = () => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { selectedGame, selectedDate, slotBooked, bookingCheck } = useSelector(state => state);
const [selectedSlot, setSelectedSlot] = useState(null);
const [name, setName] = useState('');
const [contact, setContact] = useState('');
const today = new Date().toISOString().split('T')[0];
const tomorrow = new Date();
tomorrow.setDate(new Date().getDate() + 1);
const formattedTomorrow = tomorrow.toISOString().split('T')[0];
const handleSlotClick = (slot) => {
if (bookingCheck.some(b => b.slot === slot && b.date === selectedDate)) return;
setSelectedSlot(slot);
dispatch(selectSlot(slot));
};
const validate = () => {
if (!selectedSlot) {
alert('Select your slot!!!');
return false;
}
const nameRegex = /^[A-Za-z ]+$/;
const phoneRegex = /^[0-9]{10}$/;
if (!nameRegex.test(name) || !phoneRegex.test(contact)) {
alert('Invalid Input!!!');
return false;
}
return true;
};
const handleBook = () => {
if (!validate()) return;
const bookingID = Math.floor(1000 + Math.random() * 9000);
dispatch(bookSlot({ id: bookingID, name, contact, game: selectedGame[0], slot: selectedSlot, date: selectedDate }));
dispatch(saveDetails({ id: bookingID, name, contact }));
alert(`Booking successful! Your ID is ${bookingID}`);
navigate('/');
};
const renderSlots = () => {
return slots.map(slot => {
const isBooked = bookingCheck.some(b => b.slot === slot && b.date === selectedDate);
const isSelected = selectedSlot === slot;
let color = 'green';
if (isBooked) color = 'red';
else if (isSelected) color = 'blue';
return (
<button
key={slot}
onClick={() => handleSlotClick(slot)}
style={{ backgroundColor: color, margin: '5px' }}
>
{slot}
</button>
);
});
};
return (
<div>
<h2>Game: {selectedGame[0]}</h2>
<h3>Date: {selectedDate}</h3>
<button onClick={() => navigate('/')}>Back</button>
{selectedDate === today && <p>Booking has been closed. Book your slot for {formattedTomorrow}</p>}
{selectedDate === formattedTomorrow && (
<>
<div>{renderSlots()}</div>
<input placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
<input placeholder="Contact" value={contact} onChange={(e) => setContact(e.target.value)} />
<button onClick={handleBook}>Book Now</button>
</>
)}
{selectedDate > formattedTomorrow && <p>Booking is not opened yet</p>}
</div>
);
};
export default Book;
1 | import React, { useState } from 'react'; |
2 | import { useSelector, useDispatch } from 'react-redux'; |
3 | import { bookSlot, saveDetails, selectSlot } from './action'; |
4 | import { useNavigate } from 'react-router-dom'; |
5 | |
6 | const slots = ['10AM', '11AM', '12PM', '1PM', '2PM', '3PM', '4PM']; |
7 | |
8 | const Book = () => { |
9 | const dispatch = useDispatch(); |
10 | const navigate = useNavigate(); |
11 | const { selectedGame, selectedDate, slotBooked, bookingCheck } = useSelector(state => state); |
12 | |
13 | const [selectedSlot, setSelectedSlot] = useState(null); |
14 | const [name, setName] = useState(''); |
15 | const [contact, setContact] = useState(''); |
16 | |
17 | const today = new Date().toISOString().split('T')[0]; |
18 | const tomorrow = new Date(); |
19 | tomorrow.setDate(new Date().getDate() + 1); |
20 | const formattedTomorrow = tomorrow.toISOString().split('T')[0]; |
21 | |
22 | const handleSlotClick = (slot) => { |
23 | if (bookingCheck.some(b => b.slot === slot && b.date === selectedDate)) return; |
24 | setSelectedSlot(slot); |
25 | dispatch(selectSlot(slot)); |
26 | }; |
27 | |
28 | const validate = () => { |
29 | if (!selectedSlot) { |
30 | alert('Select your slot!!!'); |
31 | return false; |
32 | } |
33 | const nameRegex = /^[A-Za-z ]+$/; |
34 | const phoneRegex = /^[0-9]{10}$/; |
35 | if (!nameRegex.test(name) || !phoneRegex.test(contact)) { |
36 | alert('Invalid Input!!!'); |
37 | return false; |
38 | } |
39 | return true; |
40 | }; |
41 | |
42 | const handleBook = () => { |
43 | if (!validate()) return; |
44 | const bookingID = Math.floor(1000 + Math.random() * 9000); |
45 | dispatch(bookSlot({ id: bookingID, name, contact, game: selectedGame[0], slot: selectedSlot, date: selectedDate })); |
46 | dispatch(saveDetails({ id: bookingID, name, contact })); |
47 | alert(`Booking successful! Your ID is ${bookingID}`); |
48 | navigate('/'); |
49 | }; |
50 | |
51 | const renderSlots = () => { |
52 | return slots.map(slot => { |
53 | const isBooked = bookingCheck.some(b => b.slot === slot && b.date === selectedDate); |
54 | const isSelected = selectedSlot === slot; |
55 | let color = 'green'; |
56 | if (isBooked) color = 'red'; |
57 | else if (isSelected) color = 'blue'; |
58 | |
59 | return ( |
60 | <button |
61 | key={slot} |
62 | onClick={() => handleSlotClick(slot)} |
63 | style={{ backgroundColor: color, margin: '5px' }} |
64 | > |
65 | {slot} |
66 | </button> |
67 | ); |
68 | }); |
69 | }; |
70 | |
71 | return ( |
72 | <div> |
73 | <h2>Game: {selectedGame[0]}</h2> |
74 | <h3>Date: {selectedDate}</h3> |
75 | <button onClick={() => navigate('/')}>Back</button> |
76 | |
77 | {selectedDate === today && <p>Booking has been closed. Book your slot for {formattedTomorrow}</p>} |
78 | {selectedDate === formattedTomorrow && ( |
79 | <> |
80 | <div>{renderSlots()}</div> |
81 | <input placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} /> |
82 | <input placeholder="Contact" value={contact} onChange={(e) => setContact(e.target.value)} /> |
83 | <button onClick={handleBook}>Book Now</button> |
84 | </> |
85 | )} |
86 | {selectedDate > formattedTomorrow && <p>Booking is not opened yet</p>} |
87 | </div> |
88 | ); |
89 | }; |
90 | |
91 | export default Book; |
Home
· 815 B · Text
Raw
import React from 'react';
import { useDispatch } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { selectGame } from './action';
const Home = () => {
const games = ['Cricket', 'Football', 'Tennis'];
const dispatch = useDispatch();
const navigate = useNavigate();
const handleBookNow = (game) => {
dispatch(selectGame(game));
navigate('/book');
};
return (
<div>
<h1>Available Games</h1>
{games.map((game) => (
<div key={game} style={{ margin: '10px', border: '1px solid black', padding: '10px' }}>
<h2>{game}</h2>
<button onClick={() => handleBookNow(game)}>Book Now</button>
</div>
))}
<button onClick={() => navigate('/search')}>Check your booking</button>
</div>
);
};
export default Home;
1 | import React from 'react'; |
2 | import { useDispatch } from 'react-redux'; |
3 | import { useNavigate } from 'react-router-dom'; |
4 | import { selectGame } from './action'; |
5 | |
6 | const Home = () => { |
7 | const games = ['Cricket', 'Football', 'Tennis']; |
8 | const dispatch = useDispatch(); |
9 | const navigate = useNavigate(); |
10 | |
11 | const handleBookNow = (game) => { |
12 | dispatch(selectGame(game)); |
13 | navigate('/book'); |
14 | }; |
15 | |
16 | return ( |
17 | <div> |
18 | <h1>Available Games</h1> |
19 | {games.map((game) => ( |
20 | <div key={game} style={{ margin: '10px', border: '1px solid black', padding: '10px' }}> |
21 | <h2>{game}</h2> |
22 | <button onClick={() => handleBookNow(game)}>Book Now</button> |
23 | </div> |
24 | ))} |
25 | <button onClick={() => navigate('/search')}>Check your booking</button> |
26 | </div> |
27 | ); |
28 | }; |
29 | |
30 | export default Home; |
31 |
Index
· 375 B · Text
Raw
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducer from './reducer';
const store = createStore(reducer);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
1 | import React from 'react'; |
2 | import ReactDOM from 'react-dom/client'; |
3 | import App from './App'; |
4 | import { Provider } from 'react-redux'; |
5 | import { createStore } from 'redux'; |
6 | import reducer from './reducer'; |
7 | |
8 | const store = createStore(reducer); |
9 | const root = ReactDOM.createRoot(document.getElementById('root')); |
10 | root.render( |
11 | <Provider store={store}> |
12 | <App /> |
13 | </Provider> |
14 | ); |
Reducer
· 1000 B · Text
Raw
import {
SELECT_GAME,
SELECT_DATE,
SELECT_SLOT,
BOOK_SLOT,
SAVE_DETAILS
} from './action';
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const formattedTomorrow = tomorrow.toISOString().split('T')[0];
const initialState = {
Games: ['Cricket', 'Football', 'Tennis'],
selectedGame: [],
selectedDate: formattedTomorrow,
slotBooked: undefined,
details: [],
bookingCheck: [],
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case SELECT_GAME:
return { ...state, selectedGame: [action.payload] };
case SELECT_DATE:
return { ...state, selectedDate: action.payload };
case SELECT_SLOT:
return { ...state, slotBooked: action.payload };
case BOOK_SLOT:
return { ...state, bookingCheck: [...state.bookingCheck, action.payload] };
case SAVE_DETAILS:
return { ...state, details: [...state.details, action.payload] };
default:
return state;
}
};
export default reducer;
1 | |
2 | import { |
3 | SELECT_GAME, |
4 | SELECT_DATE, |
5 | SELECT_SLOT, |
6 | BOOK_SLOT, |
7 | SAVE_DETAILS |
8 | } from './action'; |
9 | |
10 | const tomorrow = new Date(); |
11 | tomorrow.setDate(tomorrow.getDate() + 1); |
12 | const formattedTomorrow = tomorrow.toISOString().split('T')[0]; |
13 | |
14 | const initialState = { |
15 | Games: ['Cricket', 'Football', 'Tennis'], |
16 | selectedGame: [], |
17 | selectedDate: formattedTomorrow, |
18 | slotBooked: undefined, |
19 | details: [], |
20 | bookingCheck: [], |
21 | }; |
22 | |
23 | const reducer = (state = initialState, action) => { |
24 | switch (action.type) { |
25 | case SELECT_GAME: |
26 | return { ...state, selectedGame: [action.payload] }; |
27 | case SELECT_DATE: |
28 | return { ...state, selectedDate: action.payload }; |
29 | case SELECT_SLOT: |
30 | return { ...state, slotBooked: action.payload }; |
31 | case BOOK_SLOT: |
32 | return { ...state, bookingCheck: [...state.bookingCheck, action.payload] }; |
33 | case SAVE_DETAILS: |
34 | return { ...state, details: [...state.details, action.payload] }; |
35 | default: |
36 | return state; |
37 | } |
38 | }; |
39 | |
40 | export default reducer; |
Search
· 1.4 KiB · Text
Raw
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
const Search = () => {
const { bookingCheck } = useSelector((state) => state);
const [searchId, setSearchId] = useState('');
const [foundBooking, setFoundBooking] = useState(null);
const navigate = useNavigate();
const handleSearch = () => {
const match = bookingCheck.find(b => b.id.toString() === searchId.trim());
setFoundBooking(match || 'not_found');
};
return (
<div>
<h2>Search Booking</h2>
<input
type="text"
placeholder="Enter Booking ID"
value={searchId}
onChange={(e) => setSearchId(e.target.value)}
/>
<button onClick={handleSearch}>Search</button>
<button onClick={() => navigate('/')}>Back</button>
{bookingCheck.length === 0 && <p>No Booking happened yet</p>}
{foundBooking === 'not_found' && <p>No Booking Found</p>}
{foundBooking && foundBooking !== 'not_found' && (
<div style={{ marginTop: '10px' }}>
<p>ID: {foundBooking.id}</p>
<p>Name: {foundBooking.name}</p>
<p>Contact: {foundBooking.contact}</p>
<p>Game: {foundBooking.game}</p>
<p>Slot: {foundBooking.slot}</p>
<p>Date: {foundBooking.date}</p>
</div>
)}
</div>
);
};
export default Search;
1 | import React, { useState } from 'react'; |
2 | import { useSelector } from 'react-redux'; |
3 | import { useNavigate } from 'react-router-dom'; |
4 | |
5 | const Search = () => { |
6 | const { bookingCheck } = useSelector((state) => state); |
7 | const [searchId, setSearchId] = useState(''); |
8 | const [foundBooking, setFoundBooking] = useState(null); |
9 | const navigate = useNavigate(); |
10 | |
11 | const handleSearch = () => { |
12 | const match = bookingCheck.find(b => b.id.toString() === searchId.trim()); |
13 | setFoundBooking(match || 'not_found'); |
14 | }; |
15 | |
16 | return ( |
17 | <div> |
18 | <h2>Search Booking</h2> |
19 | <input |
20 | type="text" |
21 | placeholder="Enter Booking ID" |
22 | value={searchId} |
23 | onChange={(e) => setSearchId(e.target.value)} |
24 | /> |
25 | <button onClick={handleSearch}>Search</button> |
26 | <button onClick={() => navigate('/')}>Back</button> |
27 | |
28 | {bookingCheck.length === 0 && <p>No Booking happened yet</p>} |
29 | {foundBooking === 'not_found' && <p>No Booking Found</p>} |
30 | {foundBooking && foundBooking !== 'not_found' && ( |
31 | <div style={{ marginTop: '10px' }}> |
32 | <p>ID: {foundBooking.id}</p> |
33 | <p>Name: {foundBooking.name}</p> |
34 | <p>Contact: {foundBooking.contact}</p> |
35 | <p>Game: {foundBooking.game}</p> |
36 | <p>Slot: {foundBooking.slot}</p> |
37 | <p>Date: {foundBooking.date}</p> |
38 | </div> |
39 | )} |
40 | </div> |
41 | ); |
42 | }; |
43 | |
44 | export default Search; |
Slot
· 908 B · Text
Raw
Components/slot.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { selectSlot } from "../Action/action";
class Slots extends Component {
handleSlot = id => {
this.props.selectSlot(id);
};
render() {
// Template for each slot
// <div key={slot.id} className="slot_list">
// <h4>
// <span
// className={slot.slotStatus}
// style={{ cursor: "pointer" }}
// >
// </span>
// </h4>
// </div>
return (<div>
{/* code for slot goes here */}
</div>);
}
}
const mapStateToProps = state => {
return {
selectedGame: state.selectedGame,
bookingSlot: state.slotBooked
};
};
const mapDispatchToProps = dispatch => {
return {
selectSlot: id => dispatch(selectSlot(id))
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Slots);
1 | Components/slot.js |
2 | |
3 | import React, { Component } from "react"; |
4 | import { connect } from "react-redux"; |
5 | import { selectSlot } from "../Action/action"; |
6 | class Slots extends Component { |
7 | handleSlot = id => { |
8 | this.props.selectSlot(id); |
9 | }; |
10 | |
11 | render() { |
12 | // Template for each slot |
13 | // <div key={slot.id} className="slot_list"> |
14 | // <h4> |
15 | // <span |
16 | // className={slot.slotStatus} |
17 | // style={{ cursor: "pointer" }} |
18 | // > |
19 | |
20 | // </span> |
21 | // </h4> |
22 | // </div> |
23 | |
24 | return (<div> |
25 | {/* code for slot goes here */} |
26 | </div>); |
27 | } |
28 | } |
29 | |
30 | const mapStateToProps = state => { |
31 | return { |
32 | selectedGame: state.selectedGame, |
33 | bookingSlot: state.slotBooked |
34 | }; |
35 | }; |
36 | const mapDispatchToProps = dispatch => { |
37 | return { |
38 | selectSlot: id => dispatch(selectSlot(id)) |
39 | }; |
40 | }; |
41 | |
42 | export default connect( |
43 | mapStateToProps, |
44 | mapDispatchToProps |
45 | )(Slots); |
46 |