diff options
| -rw-r--r-- | src/components/Guestbook.jsx | 39 | ||||
| -rw-r--r-- | src/components/GuestbookForm.jsx | 25 | ||||
| -rw-r--r-- | src/layouts/Default.astro | 23 | ||||
| -rw-r--r-- | src/styles/GuestbookForm.css | 23 |
4 files changed, 74 insertions, 36 deletions
diff --git a/src/components/Guestbook.jsx b/src/components/Guestbook.jsx index a959b5a..5935d04 100644 --- a/src/components/Guestbook.jsx +++ b/src/components/Guestbook.jsx @@ -7,31 +7,52 @@ import GuestbookForm from "./GuestbookForm.jsx"; class Guestbook extends Component { state = { message: null, - error: null + error: null, + page: 1, }; - fetchMessages = async () => { + fetchMessages = async (page) => { + const perPage = 10; + try { - const message = await pb.collection('guestbook').getFullList({ + const result = await pb.collection('guestbook').getList(page, perPage, { sort: '-created', }); - this.setState({ message }); + this.setState({ + message: result.items, + totalPages: result.totalPages + }); } catch (error) { this.setState({ error: `Failed to fetch data: ${error.message}` }); console.error('Failed to fetch data:', error); } } + refresh = async () => { + await this.fetchMessages(this.state.page); + } + async componentDidMount() { - await this.fetchMessages(); + await this.fetchMessages(this.state.page); } - refresh = async () => { - await this.fetchMessages(); + handleNext = async () => { + const nextPage = this.state.page + 1; + if (nextPage > this.state.totalPages) { + return; + } + this.setState({ page: nextPage }); + await this.fetchMessages(nextPage); + } + + handlePrevious = async () => { + const previousPage = this.state.page - 1; + this.setState({ page: previousPage }); + await this.fetchMessages(previousPage); } render() { - const { message, error } = this.state; + const { message, error, page, totalPages } = this.state; return ( <div> @@ -52,6 +73,8 @@ class Guestbook extends Component { ))} </div> )} + {page > 1 && <button class="margin" onClick={this.handlePrevious}>Previous</button>} + {page < totalPages && <button class="margin" onClick={this.handleNext}>Next</button>} </div> ); } diff --git a/src/components/GuestbookForm.jsx b/src/components/GuestbookForm.jsx index e2283f0..56f3930 100644 --- a/src/components/GuestbookForm.jsx +++ b/src/components/GuestbookForm.jsx @@ -20,6 +20,9 @@ class GuestbookForm extends Component { e.preventDefault(); if (this.state.isMessageSent) { + this.setState({ + errorMessage: 'You have already sent a message.', + }); return; } @@ -58,22 +61,20 @@ class GuestbookForm extends Component { render() { return ( - <div class="card"> + <div className="card"> <form onSubmit={this.handleSubmit}> <h2>Submit Message</h2> - <label for="name">Name</label> - <input type="text" name="name" placeholder="John Doe" required value={this.state.name} - onChange={this.handleChange}/> - <label for="website">Your Website</label> - <input type="url" name="website" placeholder="https://example.com (optional)" - value={this.state.website} onChange={this.handleChange}/> - <label for="message">Message (Supports <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank">Markdown</a>)</label> + <label htmlFor="name">Name</label> + <input type="text" name="name" placeholder="John Doe" required value={this.state.name} onChange={this.handleChange} disabled={this.state.isMessageSent}/> + <label htmlFor="website">Your Website (Optional)</label> + <input type="url" name="website" placeholder="https://example.com" value={this.state.website} onChange={this.handleChange} disabled={this.state.isMessageSent}/> + <label htmlFor="message">Message (Supports <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank">Markdown</a>)</label> <textarea name="message" placeholder="Enter your message here." required value={this.state.message} - onChange={this.handleChange}></textarea> - <button type="submit">Send</button> + onChange={this.handleChange} disabled={this.state.isMessageSent}></textarea> + <button type="submit" disabled={this.state.isMessageSent}>Send</button> </form> - {this.state.errorMessage && <p dangerouslySetInnerHTML={{ __html: this.state.errorMessage }} />} - {this.state.isMessageSent && <p>Sent successfully!</p>} + {this.state.errorMessage && <p dangerouslySetInnerHTML={{__html: this.state.errorMessage}}/>} + {this.state.isMessageSent && !this.state.errorMessage && <p>Sent successfully!</p>} </div> ); } diff --git a/src/layouts/Default.astro b/src/layouts/Default.astro index c0eb569..2181562 100644 --- a/src/layouts/Default.astro +++ b/src/layouts/Default.astro @@ -100,6 +100,29 @@ const date = new Date(); color: #609460; } + button { + padding: 10px 20px 10px 20px; + border-radius: 5px; + border: none; + background-color: #609460; + color: white; + cursor: pointer; + transition: ease-in-out 0.2s; + } + + button:hover { + background-color: #486e48; + transition: ease-in-out 0.2s; + } + + button:active { + background-color: #243824; + } + + .margin { + margin: 0.5em; + } + code { font-family: Menlo, diff --git a/src/styles/GuestbookForm.css b/src/styles/GuestbookForm.css index 0ad343c..2dd3bbf 100644 --- a/src/styles/GuestbookForm.css +++ b/src/styles/GuestbookForm.css @@ -18,21 +18,12 @@ resize: none; } -.card form button { - padding: 10px; - border-radius: 5px; - border: none; - background-color: #609460; - color: white; - cursor: pointer; - transition: ease-in-out 0.2s; -} - -.card form button:hover { - background-color: #486e48; - transition: ease-in-out 0.2s; -} -.card form button:active { - background-color: #243824; +.card form input:disabled, +.card form textarea:disabled, +.card form button:disabled { + background: #5a5a5a; + border-color: #5a5a5a; + color: #c7c7c7; + cursor: not-allowed; } |
