|
1 | 1 | import React, { useState, useContext } from 'react'; |
2 | 2 | import { Link, useNavigate } from 'react-router-dom'; |
3 | 3 |
|
4 | | -import { useFirestore, useFirestoreDocData } from 'reactfire'; |
| 4 | +import { useFirestore, useFirestoreDocData, useUser } from 'reactfire'; |
5 | 5 |
|
6 | 6 | import { |
7 | 7 | Dialog, |
@@ -30,6 +30,9 @@ const CheckoutDialog = () => { |
30 | 30 | const activeLibraryID = useContext(ActiveLibraryID); |
31 | 31 | if (!activeLibraryID) throw new Error('No active library ID!'); |
32 | 32 |
|
| 33 | + const activeUser = useUser().data; |
| 34 | + if (!activeUser) throw new Error('No active user!'); |
| 35 | + |
33 | 36 | const params = useParams() as any; |
34 | 37 |
|
35 | 38 | if (params === null) throw new Error('No checkout specified.'); |
@@ -103,60 +106,141 @@ const CheckoutDialog = () => { |
103 | 106 | maxWidth="lg" |
104 | 107 | > |
105 | 108 | <DialogTitle> |
106 | | - Checkout Info <Chip label={checkout.timeIn ? 'Returned' : 'Active'} /> |
| 109 | + Checkout Info{' '} |
| 110 | + <Chip |
| 111 | + color={checkout.timeIn ? 'default' : 'primary'} |
| 112 | + label={checkout.timeIn ? 'Returned' : 'Active'} |
| 113 | + /> |
107 | 114 | </DialogTitle> |
108 | 115 | <DialogContent> |
109 | 116 | <DialogContentText> |
110 | | - User:{' '} |
111 | | - {(libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
| 117 | + {(libraryDoc.userPermissions.MANAGE_USERS.includes(activeUser.uid) || |
112 | 118 | libraryDoc.ownerUserID === user.uid) && ( |
113 | | - <Link to={`/users/${user.ID}`}> |
114 | | - {user.firstName} {user.lastName} |
115 | | - </Link> |
| 119 | + <Link to={`/users/${user.ID}`}>User: </Link> |
116 | 120 | )} |
117 | 121 | {!( |
118 | | - libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
| 122 | + libraryDoc.userPermissions.MANAGE_USERS.includes(activeUser.uid) || |
119 | 123 | libraryDoc.ownerUserID === user.uid |
120 | | - ) && ( |
121 | | - <> |
122 | | - {user.firstName} {user.lastName} |
123 | | - </> |
124 | | - )} |
| 124 | + ) && <>User: </>} |
| 125 | + <Chip |
| 126 | + sx={{ |
| 127 | + marginInline: 1, |
| 128 | + }} |
| 129 | + onClick={() => { |
| 130 | + navigator.clipboard |
| 131 | + .writeText(`${user.firstName} ${user.lastName}`) |
| 132 | + .then(() => { |
| 133 | + NotificationHandler.addNotification({ |
| 134 | + message: 'Name copied to clipboard!', |
| 135 | + severity: 'success', |
| 136 | + timeout: 1000, |
| 137 | + }); |
| 138 | + }); |
| 139 | + }} |
| 140 | + label={`${user.firstName} ${user.lastName}`} |
| 141 | + /> |
| 142 | + <Chip |
| 143 | + sx={{ |
| 144 | + marginInline: 1, |
| 145 | + }} |
| 146 | + onClick={() => { |
| 147 | + navigator.clipboard.writeText(user.email).then(() => { |
| 148 | + NotificationHandler.addNotification({ |
| 149 | + message: 'Email copied to clipboard!', |
| 150 | + severity: 'success', |
| 151 | + timeout: 1000, |
| 152 | + }); |
| 153 | + }); |
| 154 | + }} |
| 155 | + label={user.email} |
| 156 | + /> |
| 157 | + <br /> |
| 158 | + <br /> |
| 159 | + <Link to={`/books/${book.ID}`}>Book: </Link> |
| 160 | + <Chip |
| 161 | + sx={{ |
| 162 | + marginInline: 1, |
| 163 | + }} |
| 164 | + onClick={() => { |
| 165 | + navigator.clipboard.writeText(book.volumeInfo.title).then(() => { |
| 166 | + NotificationHandler.addNotification({ |
| 167 | + message: 'Title copied to clipboard!', |
| 168 | + severity: 'success', |
| 169 | + timeout: 1000, |
| 170 | + }); |
| 171 | + }); |
| 172 | + }} |
| 173 | + label={book.volumeInfo.title} |
| 174 | + /> |
| 175 | + <Chip |
| 176 | + sx={{ |
| 177 | + marginInline: 1, |
| 178 | + }} |
| 179 | + onClick={() => { |
| 180 | + navigator.clipboard |
| 181 | + .writeText(book.volumeInfo.subtitle) |
| 182 | + .then(() => { |
| 183 | + NotificationHandler.addNotification({ |
| 184 | + message: 'Subtitle copied to clipboard!', |
| 185 | + severity: 'success', |
| 186 | + timeout: 1000, |
| 187 | + }); |
| 188 | + }); |
| 189 | + }} |
| 190 | + label={book.volumeInfo.subtitle} |
| 191 | + /> |
125 | 192 | <br /> |
126 | | - Book:{' '} |
127 | | - <Link to={`/books/${book.ID}`}> |
128 | | - {book.volumeInfo.title} <i>{book.volumeInfo.subtitle}</i> |
129 | | - </Link> |
130 | 193 | <br /> |
131 | | - Copy: #{copy.identifier} |
| 194 | + Copy:{' '} |
| 195 | + <Chip |
| 196 | + sx={{ |
| 197 | + marginInline: 1, |
| 198 | + }} |
| 199 | + onClick={() => { |
| 200 | + navigator.clipboard.writeText(copy.identifier).then(() => { |
| 201 | + NotificationHandler.addNotification({ |
| 202 | + message: 'Copy identifier copied to clipboard!', |
| 203 | + severity: 'success', |
| 204 | + timeout: 1000, |
| 205 | + }); |
| 206 | + }); |
| 207 | + }} |
| 208 | + label={copy.identifier} |
| 209 | + /> |
132 | 210 | </DialogContentText> |
133 | 211 | <hr /> |
134 | 212 | <div> |
135 | 213 | <ul> |
136 | 214 | <li> |
137 | 215 | <b>Time Out:</b>{' '} |
138 | | - {(libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
| 216 | + {(libraryDoc.userPermissions.MANAGE_USERS.includes( |
| 217 | + activeUser.uid |
| 218 | + ) || |
139 | 219 | libraryDoc.ownerUserID === user.uid) && ( |
140 | 220 | <Link to={`/users/${checkout.checkedOutBy}`}> |
141 | 221 | {checkout?.timeOut?.toDate()?.toLocaleString() || ''} |
142 | 222 | </Link> |
143 | 223 | )} |
144 | 224 | {!( |
145 | | - libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
146 | | - libraryDoc.ownerUserID === user.uid |
| 225 | + libraryDoc.userPermissions.MANAGE_USERS.includes( |
| 226 | + activeUser.uid |
| 227 | + ) || libraryDoc.ownerUserID === user.uid |
147 | 228 | ) && <>{checkout?.timeOut?.toDate()?.toLocaleString() || ''}</>} |
148 | 229 | </li> |
149 | 230 | <li> |
150 | 231 | <b>Time In:</b>{' '} |
151 | | - {(libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
| 232 | + {(libraryDoc.userPermissions.MANAGE_USERS.includes( |
| 233 | + activeUser.uid |
| 234 | + ) || |
152 | 235 | libraryDoc.ownerUserID === user.uid) && ( |
153 | 236 | <Link to={`/users/${checkout.checkedInBy}`}> |
154 | 237 | {checkout?.timeIn?.toDate()?.toLocaleString() || ''} |
155 | 238 | </Link> |
156 | 239 | )} |
157 | 240 | {!( |
158 | | - libraryDoc.userPermissions.MANAGE_USERS.includes(user.uid) || |
159 | | - libraryDoc.ownerUserID === user.uid |
| 241 | + libraryDoc.userPermissions.MANAGE_USERS.includes( |
| 242 | + activeUser.uid |
| 243 | + ) || libraryDoc.ownerUserID === user.uid |
160 | 244 | ) && <>{checkout?.timeIn?.toDate()?.toLocaleString() || ''}</>} |
161 | 245 | </li> |
162 | 246 | <br /> |
@@ -193,6 +277,18 @@ const CheckoutDialog = () => { |
193 | 277 | </div> |
194 | 278 | </DialogContent> |
195 | 279 | <DialogActions> |
| 280 | + {!checkout.timeIn && ( |
| 281 | + <Button |
| 282 | + onClick={() => { |
| 283 | + window.open( |
| 284 | + `mailto:${user.email}?subject=Your book, ${book.volumeInfo.title}, will be due soon!&body=Hello ${user.firstName} ${user.lastName},%0D%0A%0D%0AThis is a reminder that your book, ${book.volumeInfo.title} (https://bsclibrary.net/books/${book.ID}), is due soon.%0D%0A%0D%0APlease return it or renew it on our website (https://bsclibrary.net/account).%0D%0A%0D%0AThank you,%0D%0A%0D%0A${libraryDoc.name}%0D%0Ahttps://bsclibrary.net` |
| 285 | + ); |
| 286 | + }} |
| 287 | + color="primary" |
| 288 | + > |
| 289 | + Generate "Due Soon" Email |
| 290 | + </Button> |
| 291 | + )} |
196 | 292 | <Button |
197 | 293 | disabled={checkout.timeIn !== null} |
198 | 294 | onClick={() => { |
|
0 commit comments