1 | import React, {useState, useEffect} from 'react'
|
---|
2 | import {Header} from "./Header";
|
---|
3 | import {Link, useNavigate} from "react-router-dom";
|
---|
4 | import {Button, Card, DatePicker, Form, Image, Input, Modal, notification, Rate, Spin, Upload} from "antd";
|
---|
5 | import placeholderImage from '../src/Assets/placeholder.png'
|
---|
6 | import AddNewReservation from "./Dashboard/AddNewReservation";
|
---|
7 | import axios from "axios";
|
---|
8 | import env from "./env";
|
---|
9 | import Review from "./Dashboard/Review";
|
---|
10 | import {PlusOutlined} from "@ant-design/icons";
|
---|
11 |
|
---|
12 | const FrontPage = ({user, logout}) => {
|
---|
13 | const [restaurant, setRestaurant] = useState({name:'Sample Restaurant name', address: 'Sample street 1', city:'Sample'});
|
---|
14 | const [newReservationModal, setNewReservationModal] = useState(false);
|
---|
15 | const [saveModalLoading, setSaveModalLoading] = useState(false);
|
---|
16 | const [newReviewModal, setNewReviewModal] = useState(false);
|
---|
17 | const [loading, setLoading] = useState(true);
|
---|
18 | const [refreshToggle, setRefreshToggle] = useState(false);
|
---|
19 | const history = useNavigate();
|
---|
20 | const [filteredMenuItems, setFilteredMenuItems] = useState([]);
|
---|
21 |
|
---|
22 | useEffect(()=>{
|
---|
23 | setLoading(true);
|
---|
24 | axios.get(env.api + 'Restaurants').then(res=>{
|
---|
25 | setRestaurant(res.data);
|
---|
26 | console.log(user);
|
---|
27 | if(!user || !user.isVip){
|
---|
28 | setFilteredMenuItems(res.data.menu.filter(x => !x.isVipOnly));
|
---|
29 | }else{
|
---|
30 | setFilteredMenuItems(res.data.menu.sort((x,y) => x.isVipOnly ? -1 : 1));
|
---|
31 | }
|
---|
32 | setLoading(false);
|
---|
33 | });
|
---|
34 | },[user])
|
---|
35 |
|
---|
36 | useEffect(()=>{
|
---|
37 | if(user && !user.isConfirmed) {
|
---|
38 | notification['warning']({
|
---|
39 | message: <p>Вашиот емаил не е потврден. <a href={'/confirm-email'}>Потврдете го тука</a></p>
|
---|
40 | });
|
---|
41 | }
|
---|
42 | },[user])
|
---|
43 |
|
---|
44 | const updateSearchValue = (value) => {
|
---|
45 | const val = value.target.value.toLowerCase();
|
---|
46 | setFilteredMenuItems(items=>{
|
---|
47 | if(val.length==0){
|
---|
48 | return restaurant.menu;
|
---|
49 | }
|
---|
50 | const its = val.split(' ');
|
---|
51 | let allItems = []
|
---|
52 | if(!user || !user.isVip){
|
---|
53 | allItems = [...restaurant.menu.filter(x => !x.isVipOnly)]
|
---|
54 | }else{
|
---|
55 | allItems = [...restaurant.menu.sort(x => x.isVipOnly)]
|
---|
56 | }
|
---|
57 | for(let it of its){
|
---|
58 | if(it.length>0)
|
---|
59 | allItems = allItems.filter(x => !x.alergens.includes(it));
|
---|
60 | }
|
---|
61 | return allItems;
|
---|
62 | })
|
---|
63 | }
|
---|
64 |
|
---|
65 | const saveNewReview = data =>{
|
---|
66 | setSaveModalLoading(true)
|
---|
67 | axios.post(env.api + 'Reviews',data,{ headers: {Authorization: localStorage.getItem('Auth')}}).then(res=>{
|
---|
68 | setNewReviewModal(false)
|
---|
69 | setSaveModalLoading(false)
|
---|
70 | notification['success']({
|
---|
71 | message: 'Успешно зачувано',
|
---|
72 | });
|
---|
73 | setRefreshToggle(ref => !ref);
|
---|
74 | }).catch(err=>{
|
---|
75 | setSaveModalLoading(false)
|
---|
76 | notification['error']({
|
---|
77 | message: 'Се случи проблем при зачувување',
|
---|
78 | });
|
---|
79 | });
|
---|
80 | }
|
---|
81 |
|
---|
82 | return(
|
---|
83 | <div>
|
---|
84 | <Header onClickButton={!user?()=>history('/login'):logout} buttonText={!user?'Најави се':'Одјави се'} isVip={user && user.isVip}/>
|
---|
85 | {loading ? <Spin style={{margin: 20}}/> :
|
---|
86 | <div style={{
|
---|
87 | height: '400px',
|
---|
88 | width: '100%',
|
---|
89 | borderTop: '1px solid gray',
|
---|
90 | padding: '20px'
|
---|
91 | }}>
|
---|
92 | <div id={'businessFrontImage'}>
|
---|
93 | <Image
|
---|
94 | src={restaurant.base64Image}
|
---|
95 | id={'businessFrontInsideImage'}
|
---|
96 | placeholder={
|
---|
97 | <img
|
---|
98 | src={placeholderImage}
|
---|
99 | alt={'place'}
|
---|
100 | style={{width: '100%', height: '100%'}}
|
---|
101 | />
|
---|
102 | }
|
---|
103 | wrapperStyle={{overflow: 'hidden', width: '100%'}}
|
---|
104 | style={{width: '100%', height: '100%', margin: 'auto', objectFit: 'cover'}}>
|
---|
105 | </Image>
|
---|
106 | </div>
|
---|
107 | <div id={'businessFrontInfo'}>
|
---|
108 | <div style={{
|
---|
109 | width: '100%',
|
---|
110 | height: '100%',
|
---|
111 | display: 'flex',
|
---|
112 | flexDirection: 'column',
|
---|
113 | justifyContent: 'space-between'
|
---|
114 | }}>
|
---|
115 | <div style={{flexGrow: 1, fontSize: '20px', fontWeight: '500', textAlign: 'start'}}>
|
---|
116 | {restaurant.name}
|
---|
117 | <div style={{
|
---|
118 | color: 'gray',
|
---|
119 | fontSize: '10px'
|
---|
120 | }}>{restaurant.address}, {restaurant.phone}</div>
|
---|
121 | </div>
|
---|
122 | <Button onClick={() => setNewReservationModal(true)}
|
---|
123 | style={{width: '100%', marginTop: '5px'}} type={'primary'}>Резервирај</Button>
|
---|
124 | </div>
|
---|
125 |
|
---|
126 | </div>
|
---|
127 | <div style={{textAlign: 'start', backgroundColor: '#F2F2F2'}}>
|
---|
128 | <div style={{
|
---|
129 | width: '100%',
|
---|
130 | height:'75px',
|
---|
131 | backgroundColor: 'white',
|
---|
132 | padding: '20px',
|
---|
133 | border: '1px solid lightgray'
|
---|
134 | }} >
|
---|
135 | <h2 style={{float: 'left'}}>Мени</h2>
|
---|
136 | <Input.Search onChange={updateSearchValue} placeholder={'Филтрирај алергени'} style={{float:'right', width:'200px'}}/>
|
---|
137 | </div>
|
---|
138 | {filteredMenuItems.map(el =>
|
---|
139 | <Card
|
---|
140 | key={el.id}
|
---|
141 | title={el.title}
|
---|
142 | extra={el.isVipOnly ? <span style={{color:'orange',fontWeight:'bold'}}>VIP </span>:''}
|
---|
143 | style={{ width: 280, display:'inline-block', margin:'10px',verticalAlign:'middle' }}
|
---|
144 | size="small"
|
---|
145 | cover={el.image != "data:image/png;base64," ? <img style={{cursor: 'pointer'}} src={el.image} alt="avatar"
|
---|
146 | height='100px' width={'270px'}/> : ''}
|
---|
147 | >
|
---|
148 | <p>{el.description}</p>
|
---|
149 | <p>Алергени: {el.alergens.length ==0 ? 'Нема' : el.alergens}</p>
|
---|
150 | <b>{el.price} ден.</b>
|
---|
151 | </Card>
|
---|
152 | )}
|
---|
153 | <Review user={user} front refresh={refreshToggle} setVisible={setNewReviewModal}/>
|
---|
154 | </div>
|
---|
155 | </div>
|
---|
156 | }
|
---|
157 | <Modal
|
---|
158 | style={{top: 20}}
|
---|
159 | width={'700px'}
|
---|
160 | title="Нова Резервација"
|
---|
161 | footer={[
|
---|
162 | <Button form="newResForm" key="submit" htmlType="submit" type={'primary'} loading={saveModalLoading}>
|
---|
163 | Прати
|
---|
164 | </Button>
|
---|
165 | ]}
|
---|
166 | onCancel={()=>setNewReservationModal(false)}
|
---|
167 | visible={newReservationModal}>
|
---|
168 | <AddNewReservation setModalSaveLoading={setSaveModalLoading} setModalVisible={setNewReservationModal} />
|
---|
169 | </Modal>
|
---|
170 | <Modal
|
---|
171 | style={{top: 20}}
|
---|
172 | width={'700px'}
|
---|
173 | title="Нова оценка"
|
---|
174 | footer={[
|
---|
175 | <Button form="newReviewForm" key="submit" htmlType="submit" type={'primary'} loading={saveModalLoading}>
|
---|
176 | Прати
|
---|
177 | </Button>
|
---|
178 | ]}
|
---|
179 | onCancel={()=>setNewReviewModal(false)}
|
---|
180 | visible={newReviewModal}>
|
---|
181 | <Form onFinish={saveNewReview}
|
---|
182 | id={'newReviewForm'}
|
---|
183 | onFinishFailed={()=>
|
---|
184 | notification['error']({
|
---|
185 | message: 'Ве молиме поправете ги сите грешки пред зачувување!',
|
---|
186 | })}>
|
---|
187 | <Form.Item
|
---|
188 | label="Наслов"
|
---|
189 | name="title"
|
---|
190 | rules={[
|
---|
191 | {
|
---|
192 | required: true,
|
---|
193 | message: 'Ве молиме внесете наслов!',
|
---|
194 | },
|
---|
195 | ]}
|
---|
196 | >
|
---|
197 | <Input/>
|
---|
198 | </Form.Item>
|
---|
199 | <Form.Item
|
---|
200 | label="Опис"
|
---|
201 | name="description"
|
---|
202 | rules={[
|
---|
203 | {
|
---|
204 | required: true,
|
---|
205 | message: 'Ве молиме внесете опис!',
|
---|
206 | },
|
---|
207 | ]}
|
---|
208 | >
|
---|
209 | <Input.TextArea rows={4}/>
|
---|
210 | </Form.Item>
|
---|
211 | <Form.Item
|
---|
212 | label="Оценка"
|
---|
213 | name="stars"
|
---|
214 | rules={[
|
---|
215 | {
|
---|
216 | required: true,
|
---|
217 | message: 'Ве молиме внесете оценка!',
|
---|
218 | },
|
---|
219 | ]}
|
---|
220 | >
|
---|
221 | <Rate/>
|
---|
222 | </Form.Item>
|
---|
223 | </Form>
|
---|
224 | </Modal>
|
---|
225 | </div>
|
---|
226 | )
|
---|
227 | }
|
---|
228 | export default FrontPage; |
---|