@@ -59,8 +59,8 @@ app.get('/wiki/:title', (req, res) => {
5959 return res . status ( 404 ) . send ( 'Wiki not found' ) ;
6060 }
6161
62- // HTML generation inside template literal
63- res . send ( `
62+ // HTML generation inside template literal
63+ res . send ( `
6464 <!DOCTYPE html>
6565 <html lang="en">
6666 <head>
@@ -99,48 +99,21 @@ res.send(`
9999
100100 <div class="comment-section">
101101 <h3>Comments</h3>
102- const htmlOutput = wiki.comments.slice(-7).map(comment => {
103- return `
104- < div class = "comment" id = "comment-${comment.id}" >
105- < div class = "comment-author" >
106- ${ comment . author } < small > (${ new Date ( comment . createdAt ) . toLocaleString ( ) } )</ small >
107- </ div >
108- < div class = "comment-content" > $ { escapeHtml ( comment . content ) } < / d i v >
109- ${comment . replies . length > 0 ? comment . replies . map ( reply => {
102+ ${ wiki . comments . slice ( - 7 ) . map ( comment => {
110103 return `
111- <div class="comment-reply">
112- <strong>${ reply . author } </strong>: ${ escapeHtml ( reply . content ) }
113- <small>(${ new Date ( reply . createdAt ) . toLocaleString ( ) } )</small>
114- </div>
115- ` ;
116- } ) . join ( '' ) : '' }
117- </div >
118- `;
119- }).join('');
120-
121- // Use the escapeHtml function to safely escape user input
122- function escapeHtml(str) {
123- return str.replace(/[&<>"'` ] / g , function ( match ) {
124- const escape = {
125- '&' : '&' ,
126- '<' : '<' ,
127- '>' : '>' ,
128- '"' : '"' ,
129- "'" : ''' ,
130- "`" : '`'
131- } ;
132- return escape [ match ] ;
133- } ) ;
134- }
135-
136- // Output the HTML
137- console . log ( htmlOutput ) ;
138-
139- `;
140- }).join('') : ''}
141- </div>
142- ` ;
143- } ) . join ( '' ) } )
104+ <div class="comment" id="comment-${ comment . id } ">
105+ <div class="comment-author">
106+ ${ comment . author } <small>(${ new Date ( comment . createdAt ) . toLocaleString ( ) } )</small>
107+ </div>
108+ <div class="comment-content">${ escapeHtml ( comment . content ) } </div>
109+ ${ comment . replies . length > 0 ? comment . replies . map ( reply => {
110+ return `
111+ <div class="comment-reply">
112+ <strong>${ reply . author } </strong>: ${ escapeHtml ( reply . content ) }
113+ <small>(${ new Date ( reply . createdAt ) . toLocaleString ( ) } )</small>
114+ </div>
115+ ` ;
116+ } ) . join ( '' ) : '' }
144117 </div>
145118 ` ;
146119 } ) . join ( '' ) }
@@ -153,46 +126,57 @@ console.log(htmlOutput);
153126 </div>
154127
155128 <script>
129+ function escapeHtml(str) {
130+ return str.replace(/[&<>"'` ] / g , function ( match ) {
131+ const escape = {
132+ '&' : '&' ,
133+ '<' : '<' ,
134+ '>' : '>' ,
135+ '"' : '"' ,
136+ "'" : ''' ,
137+ "`" : '`'
138+ } ;
139+ return escape [ match ] ;
140+ } ) ;
141+ }
142+
156143 function submitComment ( ) {
157144 const content = document . getElementById ( 'comment-content' ) . value ;
158145 fetch ( 'https://api.ipify.org?format=json' )
159146 . then ( response => response . json ( ) )
160147 . then ( data => {
161148 const ip = data . ip ;
162- // Use the IP as needed
163- console.log(ip);
149+ const urlParams = new URLSearchParams ( window . location . search ) ;
150+ const user = atob ( urlParams . get ( 'user' ) ) || ip ;
151+
152+ if ( ! content . trim ( ) ) {
153+ alert ( 'Comment content cannot be empty' ) ;
154+ return ;
155+ }
156+
157+ fetch ( '/api/wikis/${wiki.id}/comments' , {
158+ method : 'POST' ,
159+ headers : { 'Content-Type' : 'application/json' } ,
160+ body : JSON . stringify ( { user : btoa ( user ) , content : content } )
161+ } )
162+ . then ( response => response . json ( ) )
163+ . then ( comment => {
164+ // Append new comment to the comment section
165+ const commentSection = document . querySelector ( '.comment-section' ) ;
166+ commentSection . innerHTML += `
167+ <div class="comment" id="comment-${ comment . id } ">
168+ <div class="comment-author">${ comment . author } </div>
169+ <div class="comment-content">${ comment . content } </div>
170+ </div>
171+ ` ;
172+ } )
173+ . catch ( error => console . error ( 'Error adding comment:' , error ) ) ;
164174 } ) ;
165- const urlParams = new URLSearchParams(window.location.search);
166- const user = atob(urlParams.get('user')) || ip;
167-
168- if (!content.trim()) {
169- alert('Comment content cannot be empty');
170- return;
171- }
172-
173- fetch('/api/wikis/${ wiki . id } /comments', {
174- method: 'POST',
175- headers: { 'Content-Type': 'application/json' },
176- body: JSON.stringify({ user: btoa(user), content: content })
177- })
178- .then(response => response.json())
179- .then(comment => {
180- // Append new comment to the comment section
181- const commentSection = document.querySelector('.comment-section');
182- commentSection.innerHTML += `
183- < div class = "comment" id = "comment-${comment.id}" >
184- < div class = "comment-author" > ${ comment . author } </ div >
185- < div class = "comment-content" > $ { comment . content } </div >
186- < / div >
187- `;
188- } )
189- . catch ( error => console . error ( 'Error adding comment:' , error ) ) ;
190175 }
191176 </script >
192177 < / body >
193178 </ html >
194- `);
195-
179+ `);
196180});
197181
198182// API: Get all wikis (without comments)
0 commit comments