55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
66 < title > {{ page.title }} | DevLabStudy</ title >
77 < link rel ="icon " type ="image/jpeg " href ="/profileIcon_g3ffyg7edeeg1.jpeg ">
8- <!-- Czcionki Google Fonts dopasowane do reszty portalu -->
8+ <!-- Czcionki Google Fonts -->
99 < link href ="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800;900&family=JetBrains+Mono:wght@400;700;800&display=swap " rel ="stylesheet ">
1010
1111 < style >
7373 position : relative;
7474 overflow : hidden;
7575 }
76- /* Cienki pasek akcentu po lewej stronie kontenera w stylu terminala */
7776 .container ::before {
7877 content : '' ;
7978 position : absolute;
106105 border : 1px solid rgba (255 , 94 , 0 , 0.2 );
107106 }
108107
109- .article-date {
110- color : var (--text-muted );
111- }
108+ .article-date { color : var (--text-muted ); }
112109
113110 .article-title {
114111 font-size : 2.4rem ;
118115 line-height : 1.2 ;
119116 }
120117
121- /* Stylizacja treści wpisu */
118+ /* Treść wpisu */
122119 .article-content {
123120 font-size : 1.05rem ;
124121 color : # cbd5e1 ;
136133 .article-content a { color : var (--accent-blue ); text-decoration : none; font-weight : 600 ; }
137134 .article-content a : hover { text-decoration : underline; }
138135
139- /* Tabeli w markdownie nadajemy inżynieryjny sznyt */
136+ /* Tabele */
140137 .article-content table {
141138 width : 100% ;
142139 border-collapse : collapse;
153150 background : rgba (0 , 210 , 255 , 0.08 );
154151 color : var (--accent-blue );
155152 }
156- .article-content tr : nth-child (even) {
157- background : rgba (255 , 255 , 255 , 0.02 );
158- }
153+ .article-content tr : nth-child (even) { background : rgba (255 , 255 , 255 , 0.02 ); }
159154
160- /* Zabezpieczenie zdjęć i kodu */
155+ /* Obrazy i kod */
161156 .article-content img {
162157 max-width : 100% ;
163158 height : auto;
185180 color : var (--accent-blue );
186181 }
187182 .article-content pre code { background : none; padding : 0 ; color : # f8fafc ; }
188-
183+
184+ /* SEKCJA INTERAKTYWNA: KUDOS / SERDUSZKO I KOMENTARZE */
185+ .post-interactions {
186+ margin-top : 50px ;
187+ padding-top : 30px ;
188+ border-top : 1px dashed var (--border );
189+ display : flex;
190+ flex-direction : column;
191+ gap : 25px ;
192+ }
193+
194+ .kudos-box {
195+ display : flex;
196+ align-items : center;
197+ justify-content : space-between;
198+ background : rgba (0 , 210 , 255 , 0.03 );
199+ border : 1px solid var (--border );
200+ padding : 20px 25px ;
201+ border-radius : 10px ;
202+ }
203+
204+ .kudos-info {
205+ font-family : 'JetBrains Mono' , monospace;
206+ font-size : 0.85rem ;
207+ color : var (--text-muted );
208+ }
209+
210+ .kudos-btn {
211+ background : rgba (255 , 94 , 0 , 0.15 );
212+ border : 1px solid rgba (255 , 94 , 0 , 0.4 );
213+ color : # fff ;
214+ padding : 10px 20px ;
215+ border-radius : 6px ;
216+ font-family : 'JetBrains Mono' , monospace;
217+ font-weight : 800 ;
218+ cursor : pointer;
219+ display : flex;
220+ align-items : center;
221+ gap : 8px ;
222+ transition : 0.2s ;
223+ }
224+ .kudos-btn : hover {
225+ background : var (--accent-contrast );
226+ transform : translateY (-2px );
227+ box-shadow : 0 5px 15px rgba (255 , 94 , 0 , 0.3 );
228+ }
229+
230+ .comments-section {
231+ background : rgba (3 , 3 , 5 , 0.6 );
232+ border : 1px solid var (--border );
233+ border-radius : 10px ;
234+ padding : 25px ;
235+ }
236+
237+ .comments-title {
238+ font-family : 'JetBrains Mono' , monospace;
239+ font-size : 0.95rem ;
240+ color : # fff ;
241+ margin : 0 0 15px 0 ;
242+ text-transform : uppercase;
243+ display : flex;
244+ align-items : center;
245+ gap : 10px ;
246+ }
247+ .comments-title ::before { content : '//' ; color : var (--accent-blue ); }
248+
249+ .comments-placeholder {
250+ color : var (--text-muted );
251+ font-size : 0.9rem ;
252+ font-family : 'JetBrains Mono' , monospace;
253+ margin : 0 0 15px 0 ;
254+ }
255+
256+ .comment-input-group {
257+ display : flex;
258+ gap : 10px ;
259+ }
260+
261+ .comment-input {
262+ flex : 1 ;
263+ background : rgba (0 , 0 , 0 , 0.5 );
264+ border : 1px solid var (--border );
265+ color : # fff ;
266+ padding : 12px 15px ;
267+ border-radius : 6px ;
268+ font-family : 'JetBrains Mono' , monospace;
269+ font-size : 0.85rem ;
270+ outline : none;
271+ }
272+ .comment-input : focus { border-color : var (--accent-blue ); }
273+
274+ .comment-submit {
275+ background : rgba (0 , 210 , 255 , 0.1 );
276+ border : 1px solid rgba (0 , 210 , 255 , 0.3 );
277+ color : var (--accent-blue );
278+ padding : 0 20px ;
279+ border-radius : 6px ;
280+ font-family : 'JetBrains Mono' , monospace;
281+ font-weight : 700 ;
282+ cursor : pointer;
283+ transition : 0.2s ;
284+ text-transform : uppercase;
285+ font-size : 0.8rem ;
286+ }
287+ .comment-submit : hover {
288+ background : var (--accent-blue );
289+ color : # 030305 ;
290+ }
291+
292+ .submitted-comments {
293+ margin-top : 15px ;
294+ display : flex;
295+ flex-direction : column;
296+ gap : 10px ;
297+ }
298+
299+ .user-comment {
300+ background : rgba (255 , 255 , 255 , 0.02 );
301+ border : 1px solid rgba (255 , 255 , 255 , 0.05 );
302+ padding : 12px 15px ;
303+ border-radius : 6px ;
304+ font-size : 0.9rem ;
305+ }
306+ .user-comment-meta {
307+ font-family : 'JetBrains Mono' , monospace;
308+ font-size : 0.75rem ;
309+ color : var (--accent-blue );
310+ margin-bottom : 4px ;
311+ }
312+
189313 footer {
190314 text-align : center;
191315 color : var (--text-muted );
199323 .container { margin : 20px 15px ; padding : 25px ; }
200324 .article-title { font-size : 1.8rem ; }
201325 .navbar { padding : 15px 20px ; }
326+ .comment-input-group { flex-direction : column; }
202327 }
203328 </ style >
204329</ head >
@@ -221,11 +346,121 @@ <h1 class="article-title">{{ page.title }}</h1>
221346 < article class ="article-content ">
222347 {{ content }}
223348 </ article >
349+
350+ <!-- SEKCJA INTERAKTYWNA (KUDOS & KOMENTARZE) -->
351+ < div class ="post-interactions ">
352+ <!-- Przycisk Kudos / Serduszko -->
353+ < div class ="kudos-box ">
354+ < div class ="kudos-info ">
355+ // DOCENIASZ MATERIAŁ? ZOSTAW SYGNAŁ KUDOS.
356+ </ div >
357+ < button class ="kudos-btn " id ="kudosBtn ">
358+ ❤️ < span id ="kudosCount "> 14</ span > Kudos
359+ </ button >
360+ </ div >
361+
362+ <!-- Panel Komentarzy / Feedbacku -->
363+ < div class ="comments-section ">
364+ < h3 class ="comments-title "> Rejestr Komentarzy & Feedback</ h3 >
365+ < p class ="comments-placeholder "> // Masz pytanie lub uwagi do konfiguracji? Zostaw wpis w lokalnym buforze:</ p >
366+
367+ < div class ="comment-input-group ">
368+ < input type ="text " id ="commentInput " class ="comment-input " placeholder ="Wpisz swój komentarz... ">
369+ < button class ="comment-submit " id ="commentSubmit "> Wyślij</ button >
370+ </ div >
371+
372+ < div class ="submitted-comments " id ="commentsList ">
373+ <!-- Dynamiczne komentarze -->
374+ </ div >
375+ </ div >
376+ </ div >
224377 </ main >
225378
226379 < footer >
227- < p > // 1 Gbps Fiber - Linux Fedora - DevLabStudy System Hub 2026</ p >
380+ < p > // 1 Gbps Fiber - Proxmox VE / MikroTik - DevLabStudy Hub 2026</ p >
228381 </ footer >
229382
383+ <!-- Skrypt obsługujący serduszka (Kudos) i lokalne komentarze -->
384+ < script >
385+ // Unikalny klucz dla konkretnego wpisu oparty na jego URL
386+ const postId = window . location . pathname ;
387+
388+ // --- OBSŁUGA KUDOS (SERDECZNEK) ---
389+ const kudosBtn = document . getElementById ( 'kudosBtn' ) ;
390+ const kudosCountSpan = document . getElementById ( 'kudosCount' ) ;
391+
392+ let kudosKey = 'devlab_kudos_' + postId ;
393+ let likedKey = 'devlab_liked_' + postId ;
394+
395+ // Pobierz stan z localStorage lub ustaw domyślną bazę
396+ let currentKudos = parseInt ( localStorage . getItem ( kudosKey ) ) || 12 ;
397+ let hasLiked = localStorage . getItem ( likedKey ) === 'true' ;
398+
399+ kudosCountSpan . textContent = currentKudos ;
400+ if ( hasLiked ) {
401+ kudosBtn . style . opacity = '0.7' ;
402+ kudosBtn . innerHTML = '❤️ <span id="kudosCount">' + currentKudos + '</span> (Zapisano)' ;
403+ }
404+
405+ kudosBtn . addEventListener ( 'click' , ( ) => {
406+ if ( ! hasLiked ) {
407+ currentKudos ++ ;
408+ hasLiked = true ;
409+ localStorage . setItem ( kudosKey , currentKudos ) ;
410+ localStorage . setItem ( likedKey , 'true' ) ;
411+
412+ kudosCountSpan . textContent = currentKudos ;
413+ kudosBtn . style . opacity = '0.7' ;
414+ kudosBtn . innerHTML = '❤️ <span id="kudosCount">' + currentKudos + '</span> (Dziękuję!)' ;
415+ }
416+ } ) ;
417+
418+ // --- OBSŁUGA LOKALNYCH KOMENTARZY ---
419+ const commentInput = document . getElementById ( 'commentInput' ) ;
420+ const commentSubmit = document . getElementById ( 'commentSubmit' ) ;
421+ const commentsList = document . getElementById ( 'commentsList' ) ;
422+
423+ let commentsKey = 'devlab_comments_' + postId ;
424+ let savedComments = JSON . parse ( localStorage . getItem ( commentsKey ) ) || [
425+ { author : "Admin (Tobiasz)" , text : "Dziennik otwarty. Piszcie, jak wam idzie optymalizacja!" , date : "2026.03.20" }
426+ ] ;
427+
428+ function renderComments ( ) {
429+ commentsList . innerHTML = '' ;
430+ savedComments . forEach ( c => {
431+ const div = document . createElement ( 'div' ) ;
432+ div . className = 'user-comment' ;
433+ div . innerHTML = `
434+ <div class="user-meta">// ${ c . author } — ${ c . date } </div>
435+ <div>${ escapeHtml ( c . text ) } </div>
436+ ` ;
437+ commentsList . appendChild ( div ) ;
438+ } ) ;
439+ }
440+
441+ commentSubmit . addEventListener ( 'click' , ( ) => {
442+ const text = commentInput . value . trim ( ) ;
443+ if ( text . length < 2 ) return ;
444+
445+ const now = new Date ( ) ;
446+ const dateStr = now . getFullYear ( ) + '.' + String ( now . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) + '.' + String ( now . getDate ( ) ) . padStart ( 2 , '0' ) ;
447+
448+ savedComments . push ( {
449+ author : "Gość (Operator)" ,
450+ text : text ,
451+ date : dateStr
452+ } ) ;
453+
454+ localStorage . setItem ( commentsKey , JSON . stringify ( savedComments ) ) ;
455+ commentInput . value = '' ;
456+ renderComments ( ) ;
457+ } ) ;
458+
459+ function escapeHtml ( str ) {
460+ return str . replace ( / & / g, "&" ) . replace ( / < / g, "<" ) . replace ( / > / g, ">" ) ;
461+ }
462+
463+ renderComments ( ) ;
464+ </ script >
230465</ body >
231466</ html >
0 commit comments