madebydanny.uk written in html, css, and a lot of JavaScript I don't understand madeydanny.uk
html css javascript

added 404.html

+181 -104
+21
404.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <title>404 Not Found</title> 5 + <meta charset="UTF-8"> 6 + <link rel ="stylesheet" href="styles.css"> 7 + <script src="script.js" defer></script> 8 + </head> 9 + <body> 10 + <h1>404 Not Found</h1> 11 + <p>The page you are looking for does not exist.</p> 12 + <p><a href="index.html">Return to Home</a></p> 13 + <hr> 14 + Cloudflare Pages retured a 404 error. 15 + <br> 16 + The file you requested at <i><url id="error-url"></url></i>could not be found. 17 + <br><br> 18 + Please check the URL for errors and try again. 19 + <hr> 20 + <p>&copy; 2024-<span id="current-year"></span> Made by Danny UK, <i>by Daniel Morrisey</i></p> 21 + </html>
+19 -104
index.html
··· 30 30 <!-- Font Awesome CDN --> 31 31 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" xintegrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer" /> 32 32 33 - <style> 34 - body { 35 - font-family: 'Fira Code', monospace; 36 - background-color: #121212; 37 - color: #e0e0e0; 38 - margin: 40px; 39 - } 40 - a { 41 - color: #f71900; 42 - text-decoration: none; 43 - } 44 - a:hover { 45 - text-decoration: underline; 46 - } 47 - hr { 48 - border: 0; 49 - height: 1px; 50 - background: #333; 51 - margin: 20px 0; 52 - } 53 - ul { 54 - list-style-type: none; 55 - padding: 0; 56 - } 57 - li { 58 - margin: 10px 0; 59 - } 60 - i { 61 - margin-right: 8px; 62 - } 63 - .title { 64 - font-size: 24px; 65 - margin-bottom: 10px; 66 - } 67 - </style> 33 + <!-- Styles --> 34 + <link rel="stylesheet" href="styles.css"> 35 + <!-- Scripts --> 36 + <script src="script.js" defer></script> 68 37 </head> 69 38 <body> 70 39 <p class="title"><b>Hello World</b> I'm Daniel Morrisey</p> ··· 74 43 <ul> 75 44 <li><a href="https://bsky.app/profile/danielmorrisey.com" target="_blank"><i class="fa-brands fa-bluesky"></i> Bluesky</a></li> 76 45 <li><a href="https://threads.com/madebydanny.uk" target="_blank"><i class="fa-brands fa-threads"></i> Threads</a></li> 46 + <li><a href="https://mastodon.social/@danielmorrisey" target="_blank"><i class="fa-brands fa-mastodon"></i> Mastodon<i>(.social)</i></a></li> 77 47 <li><a href="https://medium.com/@danielmorrisey" target="_blank"><i class="fa-brands fa-medium"></i> Medium</a></li> 78 48 <li><a href="mailto:danielmorrisey.large390@passinbox.com" target="_blank"><i class="fa-solid fa-envelope"></i> Email</a></li> 79 49 </ul> 80 50 <hr> 81 - <p>Latest Posts by Daniel Morrisey</p> 82 - 83 - <div id="loading">Fetching posts...</div> 84 - 85 - <div id="post-list" style="display: none;"></div> 86 - 87 - <div id="error-message" style="display: none;">Failed to load posts. Please try again later.</div> 88 - 89 - <script> 90 - const postList = document.getElementById('post-list'); 91 - const loadingIndicator = document.getElementById('loading'); 92 - const errorMessage = document.getElementById('error-message'); 93 - 94 - const fetchPosts = async () => { 95 - const feedUrl = 'https://medium.com/feed/@danielmorrisey'; 96 - // Using corsproxy.io instead of allorigins.win as it seems to be more reliable 97 - const proxyUrl = `https://corsproxy.io/?${encodeURIComponent(feedUrl)}`; 98 - 99 - try { 100 - const response = await fetch(proxyUrl); 101 - if (!response.ok) { 102 - throw new Error('Network response was not ok'); 103 - } 104 - const data = await response.text(); // Get response as text instead of json 105 - 106 - const parser = new DOMParser(); 107 - const xmlDoc = parser.parseFromString(data, 'text/xml'); 108 - 109 - const items = xmlDoc.querySelectorAll('item'); 110 - const postsToShow = 5; 111 - 112 - if (items.length > 0) { 113 - items.forEach((item, index) => { 114 - if (index < postsToShow) { 115 - const title = item.querySelector('title').textContent; 116 - const link = item.querySelector('link').textContent; 117 - 118 - const paragraph = document.createElement('p'); 119 - const linkElement = document.createElement('a'); 120 - const iconElement = document.createElement('i'); 121 - 122 - linkElement.href = link; 123 - linkElement.textContent = title; 124 - linkElement.target = "_blank"; 125 - 126 - iconElement.className = "fa-solid fa-arrow-up-right-from-square"; 127 - iconElement.style.marginLeft = "5px"; // Add a small space 128 - 129 - paragraph.appendChild(linkElement); 130 - paragraph.appendChild(iconElement); 131 - 132 - postList.appendChild(paragraph); 133 - } 134 - }); 135 - postList.style.display = 'block'; 136 - } else { 137 - errorMessage.textContent = "No posts found."; 138 - errorMessage.style.display = 'block'; 139 - } 140 - } catch (error) { 141 - console.error('Error fetching or parsing the feed:', error); 142 - errorMessage.style.display = 'block'; 143 - } finally { 144 - loadingIndicator.style.display = 'none'; 145 - } 146 - }; 147 - 148 - document.addEventListener('DOMContentLoaded', fetchPosts); 149 - </script> 51 + <p class="heading">Latest Posts by Daniel Morrisey</p> 52 + <p><i>This list will auto refresh</i></p> 53 + <ul id="post-list"></ul> 54 + <div id="loading"><i class="fa-solid fa-arrows-rotate fa-spin"></i>Loading…</div> 55 + <div id="error-message" style="display:none;color:red;"></div> 56 + <hr> 57 + <p class="heading">Made Possible thanks to:</p> 58 + <ul> 59 + <li><a href="https://corsproxy.io/" target="_blank"><i class="fa-solid fa-globe"></i> CORS Proxy</a></li> 60 + <li><a href="https://fontawesome.com/" target="_blank"><i class="fa-brands fa-font-awesome"></i> Font Awesome</a></li> 61 + <li><a href="https://cloudflare.com" target="_blank"><i class="fa-brands fa-cloudflare"></i> Cloudflare</a></li> 62 + </ul> 63 + <hr> 64 + <p>&copy; 2024-<span id="current-year"></span> Made by Danny UK, <i>by Daniel Morrisey</i></p> 150 65 </body> 151 66 </html>
+103
script.js
··· 1 + /* ------------------------------------------------------------------ * 2 + * Utility: set the current year 3 + * ------------------------------------------------------------------ */ 4 + document.getElementById('current-year').textContent = new Date().getFullYear(); 5 + 6 + /* ------------------------------------------------------------------ * 7 + * Configuration 8 + * ------------------------------------------------------------------ */ 9 + const CONFIG = { 10 + FEED_URL: 'https://medium.com/feed/@danielmorrisey', 11 + PROXY_URL: url => `https://corsproxy.io/?${encodeURIComponent(url)}`, 12 + POSTS_TO_SHOW: 5, 13 + REFRESH_INTERVAL_MS: 60_000, // 1 minute 14 + }; 15 + 16 + /* ------------------------------------------------------------------ * 17 + * DOM references – grab them once so we don’t query repeatedly 18 + * ------------------------------------------------------------------ */ 19 + const dom = { 20 + postList: document.getElementById('post-list'), 21 + loading: document.getElementById('loading'), 22 + errorMessage: document.getElementById('error-message') 23 + }; 24 + 25 + /* ------------------------------------------------------------------ * 26 + * Helper: show / hide UI elements 27 + * ------------------------------------------------------------------ */ 28 + function toggleVisibility(el, visible) { 29 + el.style.display = visible ? '' : 'none'; 30 + } 31 + 32 + /* ------------------------------------------------------------------ * 33 + * Helper: create a single post element 34 + * ------------------------------------------------------------------ */ 35 + function createPostItem({ title = '(no title)', link = '#' }) { 36 + const p = document.createElement('p'); 37 + const a = document.createElement('a'); 38 + const icn = document.createElement('i'); 39 + 40 + a.href = link; 41 + a.textContent = title; 42 + a.target = '_blank'; 43 + 44 + icn.className = 'fa-solid fa-arrow-up-right-from-square'; 45 + icn.style.marginLeft = '5px'; 46 + 47 + p.appendChild(a); 48 + p.appendChild(icn); 49 + return p; 50 + } 51 + 52 + /* ------------------------------------------------------------------ * 53 + * Main: fetch, parse and render the RSS feed 54 + * ------------------------------------------------------------------ */ 55 + async function fetchPosts() { 56 + toggleVisibility(dom.loading, true); 57 + toggleVisibility(dom.errorMessage, false); 58 + dom.postList.innerHTML = ''; // clear previous items 59 + 60 + try { 61 + const response = await fetch(CONFIG.PROXY_URL(CONFIG.FEED_URL)); 62 + if (!response.ok) throw new Error(`Network error: ${response.status}`); 63 + 64 + const rawXml = await response.text(); 65 + const parser = new DOMParser(); 66 + const xmlDoc = parser.parseFromString(rawXml, 'application/xml'); 67 + 68 + const items = [...xmlDoc.querySelectorAll('item')]; 69 + if (items.length === 0) throw new Error('No posts found.'); 70 + 71 + items 72 + .slice(0, CONFIG.POSTS_TO_SHOW) 73 + .map(item => ({ 74 + title: item.querySelector('title')?.textContent ?? '(no title)', 75 + link: item.querySelector('link')?.textContent ?? '#' 76 + })) 77 + .forEach(postData => dom.postList.appendChild(createPostItem(postData))); 78 + 79 + } catch (err) { 80 + console.error('RSS fetch/parse error:', err); 81 + dom.errorMessage.textContent = err.message || 'Failed to load articles.'; 82 + toggleVisibility(dom.errorMessage, true); 83 + } finally { 84 + toggleVisibility(dom.loading, false); 85 + } 86 + } 87 + 88 + /* ------------------------------------------------------------------ * 89 + * Helper: store the current URL in the hidden <url> element 90 + * ------------------------------------------------------------------ */ 91 + function setErrorUrl() { 92 + const el = document.getElementById('error-url'); 93 + if (el) el.textContent = window.location.href; 94 + } 95 + 96 + /* ------------------------------------------------------------------ * 97 + * Initialise – run once now and then on an interval 98 + * ------------------------------------------------------------------ */ 99 + document.addEventListener('DOMContentLoaded', () => { 100 + setErrorUrl(); // store the URL for your 404 page 101 + fetchPosts(); // initial load 102 + setInterval(fetchPosts, CONFIG.REFRESH_INTERVAL_MS); // repeat periodically 103 + });
+38
styles.css
··· 1 + body { 2 + font-family: 'Fira Code', monospace; 3 + background-color: #121212; 4 + color: #e0e0e0; 5 + margin: 40px; 6 + } 7 + a { 8 + color: #f71900; 9 + text-decoration: none; 10 + } 11 + a:hover { 12 + text-decoration: underline; 13 + } 14 + hr { 15 + border: 0; 16 + height: 1px; 17 + background: #333; 18 + margin: 20px 0; 19 + } 20 + ul { 21 + list-style-type: none; 22 + padding: 0; 23 + } 24 + li { 25 + margin: 10px 0; 26 + } 27 + i { 28 + margin-right: 8px; 29 + } 30 + .title { 31 + font-size: 24px; 32 + margin-bottom: 10px; 33 + } 34 + .heading { 35 + font-size: 20px; 36 + margin-top: 20px; 37 + margin-bottom: 10px; 38 + }