aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/Guestbook.jsx39
-rw-r--r--src/components/GuestbookForm.jsx25
-rw-r--r--src/layouts/Default.astro23
-rw-r--r--src/styles/GuestbookForm.css23
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;
}