diff --git a/frontend/src/pages/Stories.js b/frontend/src/pages/Stories.js new file mode 100644 index 0000000..ea51fa8 --- /dev/null +++ b/frontend/src/pages/Stories.js @@ -0,0 +1,175 @@ +export function renderStories(container) { + let posts = []; + let title = ''; + let content = ''; + let category = ''; + + // Function to fetch posts from localStorage + const fetchPosts = () => { + const storedPosts = localStorage.getItem('posts'); + if (storedPosts) { + posts = JSON.parse(storedPosts); + } + render(); // Render after fetching posts + }; + + // Function to handle form submission + const handleSubmit = (e) => { + e.preventDefault(); + + if (title && content && category) { + const newPost = { title, content, category, date: new Date().toISOString() }; + + // Add new post to the posts array + posts.unshift(newPost); + + // Save the updated posts to localStorage + localStorage.setItem('posts', JSON.stringify(posts)); + // Clear form fields + title = ''; + content = ''; + category = ''; + + render(); // Re-render after saving the post + + + } + }; + + // Function to render the DOM + const render = () => { + // Clear the container + container.innerHTML = ''; + + // Title + const titleElement = document.createElement('h1'); + titleElement.className = 'text-3xl font-bold text-center mt-10 mb-5 text-white'; // Changed to white for contrast + titleElement.innerText = 'Real Stories, Real Advice: Share Your Experience'; + container.appendChild(titleElement); + + // Flex container for posts and form + const flexContainer = document.createElement('div'); + flexContainer.className = 'flex flex-col lg:flex-row items-start gap-8 px-6 lg:px-20 mb-14'; + + // Left side - Posts + const postsContainer = document.createElement('div'); + postsContainer.className = 'flex-1 space-y-6'; + + if (posts.length === 0) { + const noPostsMessage = document.createElement('p'); + noPostsMessage.className = 'text-gray-400 text-center'; // Lightened text for dark theme + noPostsMessage.innerText = 'No posts yet. Share your experience!'; + postsContainer.appendChild(noPostsMessage); + } else { + posts.forEach((post) => { + const postElement = document.createElement('div'); + postElement.className = 'bg-gray-800 text-white shadow-lg rounded-xl p-8 border border-gray-700 hover:shadow-xl transition-all duration-300 ease-in-out'; + + const postTitle = document.createElement('h3'); + postTitle.className = 'text-2xl font-bold mb-2'; + postTitle.innerText = post.title; + postElement.appendChild(postTitle); + + const postCategory = document.createElement('p'); + postCategory.className = 'text-sm text-indigo-400 font-medium mb-6'; // Lightened category text + postCategory.innerText = post.category; + postElement.appendChild(postCategory); + + const postContent = document.createElement('p'); + postContent.className = 'text-gray-300 leading-relaxed mb-4'; // Lighter content text + postContent.innerText = post.content; + postElement.appendChild(postContent); + + const postFooter = document.createElement('div'); + postFooter.className = 'flex items-center justify-between'; + + const postDate = document.createElement('p'); + postDate.className = 'text-xs text-gray-500'; + postDate.innerText = new Date(post.date).toLocaleDateString(); + postFooter.appendChild(postDate); + + const readMoreButton = document.createElement('button'); + readMoreButton.className = 'text-indigo-400 text-sm font-medium border border-indigo-700 rounded-full px-5 py-2 hover:bg-indigo-600 hover:text-white transition-all duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'; + readMoreButton.innerText = 'Read More'; + postFooter.appendChild(readMoreButton); + + + postElement.appendChild(postFooter); + postsContainer.appendChild(postElement); + }); + } + + flexContainer.appendChild(postsContainer); + + // Right side - Form + const formContainer = document.createElement('div'); + formContainer.className = 'w-full lg:w-1/3 bg-gray-800 p-6 rounded-lg shadow-md'; + + const form = document.createElement('form'); + form.className = 'space-y-4'; + + const titleInput = document.createElement('input'); + titleInput.type = 'text'; + titleInput.placeholder = 'Title of your story'; + titleInput.value = title; + titleInput.oninput = (e) => { title = e.target.value; }; + titleInput.className = 'w-full p-3 rounded-md border border-gray-600 bg-gray-900 text-white focus:outline-none focus:border-blue-500'; + form.appendChild(titleInput); + + const contentInput = document.createElement('textarea'); + contentInput.placeholder = 'Write about your story...'; + contentInput.value = content; + contentInput.oninput = (e) => { content = e.target.value; }; + contentInput.className = 'w-full p-3 h-32 rounded-md border border-gray-600 bg-gray-900 text-white focus:outline-none focus:border-blue-500'; + form.appendChild(contentInput); + + const categorySelect = document.createElement('select'); + categorySelect.value = category; + categorySelect.onchange = (e) => { category = e.target.value; }; + categorySelect.className = 'block w-full px-4 py-2 bg-gray-900 border border-gray-600 rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 text-white'; + + const optionPlaceholder = document.createElement('option'); + optionPlaceholder.value = ''; + optionPlaceholder.disabled = true; + optionPlaceholder.innerText = 'Select Blog Category'; + categorySelect.appendChild(optionPlaceholder); + + const categories = [ + { label: 'Career and Growth', options: ['Interview Tips', 'Job Referrals', 'Career Advice', 'Networking Strategies', 'Skill Building', 'Resume & Portfolio Tips', 'Job Hunt Strategies'] }, + { label: 'Tech and Industry Trends', options: ['Latest Tech News', 'Emerging Technologies', 'Industry Analysis', 'Tech Events & Conferences'] }, + { label: 'Work Culture & Lifestyle', options: ['Work-Life Balance', 'Remote Work Tips', 'Productivity Hacks', 'Workplace Culture', 'Mental Health in Tech'] }, + { label: 'Personal Development', options: ['Personal Branding', 'Public Speaking & Communication', 'Learning New Skills', 'Freelancing Tips'] }, + ]; + + categories.forEach(categoryGroup => { + const optgroup = document.createElement('optgroup'); + optgroup.label = categoryGroup.label; + + categoryGroup.options.forEach(option => { + const optionElement = document.createElement('option'); + optionElement.value = option; + optionElement.innerText = option; + optgroup.appendChild(optionElement); + }); + + categorySelect.appendChild(optgroup); + }); + + form.appendChild(categorySelect); + + const submitButton = document.createElement('button'); + submitButton.type = 'submit'; + submitButton.className = 'w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 rounded-md focus:outline-none'; + submitButton.innerText = 'Post Experience'; + submitButton.onclick = handleSubmit; + form.appendChild(submitButton); + + formContainer.appendChild(form); + flexContainer.appendChild(formContainer); + + container.appendChild(flexContainer); + }; + + // Fetch posts from localStorage + fetchPosts(); +} diff --git a/frontend/src/styles/output.css b/frontend/src/styles/output.css index f08977f..e6d7106 100644 --- a/frontend/src/styles/output.css +++ b/frontend/src/styles/output.css @@ -600,6 +600,10 @@ video { border-width: 0; } +.fixed { + position: fixed; +} + .absolute { position: absolute; } @@ -636,6 +640,14 @@ video { top: 0.75rem; } +.right-4 { + right: 1rem; +} + +.top-4 { + top: 1rem; +} + .z-10 { z-index: 10; } @@ -658,6 +670,10 @@ video { margin-bottom: 3rem; } +.mb-14 { + margin-bottom: 3.5rem; +} + .mb-2 { margin-bottom: 0.5rem; } @@ -666,6 +682,10 @@ video { margin-bottom: 1rem; } +.mb-5 { + margin-bottom: 1.25rem; +} + .mb-6 { margin-bottom: 1.5rem; } @@ -698,6 +718,10 @@ video { margin-top: 0.25rem; } +.mt-10 { + margin-top: 2.5rem; +} + .mt-2 { margin-top: 0.5rem; } @@ -843,6 +867,10 @@ video { max-width: 1280px; } +.flex-1 { + flex: 1 1 0%; +} + .transform { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @@ -971,6 +999,10 @@ video { border-radius: 0.375rem; } +.rounded-xl { + border-radius: 0.75rem; +} + .border { border-width: 1px; } @@ -1012,6 +1044,11 @@ video { border-color: rgb(147 197 253 / var(--tw-border-opacity)); } +.border-gray-100 { + --tw-border-opacity: 1; + border-color: rgb(243 244 246 / var(--tw-border-opacity)); +} + .border-gray-200 { --tw-border-opacity: 1; border-color: rgb(229 231 235 / var(--tw-border-opacity)); @@ -1037,6 +1074,11 @@ video { border-color: rgb(74 222 128 / var(--tw-border-opacity)); } +.border-indigo-100 { + --tw-border-opacity: 1; + border-color: rgb(224 231 255 / var(--tw-border-opacity)); +} + .border-indigo-500 { --tw-border-opacity: 1; border-color: rgb(99 102 241 / var(--tw-border-opacity)); @@ -1051,6 +1093,16 @@ video { border-color: transparent; } +.border-gray-600 { + --tw-border-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-border-opacity)); +} + +.border-indigo-700 { + --tw-border-opacity: 1; + border-color: rgb(67 56 202 / var(--tw-border-opacity)); +} + .bg-\[\#8b5cf6\] { --tw-bg-opacity: 1; background-color: rgb(139 92 246 / var(--tw-bg-opacity)); @@ -1146,6 +1198,16 @@ video { background-color: rgb(254 249 195 / var(--tw-bg-opacity)); } +.bg-gray-500 { + --tw-bg-opacity: 1; + background-color: rgb(107 114 128 / var(--tw-bg-opacity)); +} + +.bg-gray-900 { + --tw-bg-opacity: 1; + background-color: rgb(17 24 39 / var(--tw-bg-opacity)); +} + .object-cover { -o-object-fit: cover; object-fit: cover; @@ -1243,6 +1305,11 @@ video { padding-bottom: 2rem; } +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + .pb-2 { padding-bottom: 0.5rem; } @@ -1315,6 +1382,11 @@ video { line-height: 1.75rem; } +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + .font-bold { font-weight: 700; } @@ -1403,6 +1475,11 @@ video { color: rgb(22 101 52 / var(--tw-text-opacity)); } +.text-indigo-500 { + --tw-text-opacity: 1; + color: rgb(99 102 241 / var(--tw-text-opacity)); +} + .text-indigo-600 { --tw-text-opacity: 1; color: rgb(79 70 229 / var(--tw-text-opacity)); @@ -1453,6 +1530,16 @@ video { color: rgb(133 77 14 / var(--tw-text-opacity)); } +.text-gray-300 { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.text-indigo-400 { + --tw-text-opacity: 1; + color: rgb(129 140 248 / var(--tw-text-opacity)); +} + .shadow-lg { --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); @@ -1559,6 +1646,11 @@ body.dark-mode { background-color: rgb(117 63 241 / var(--tw-bg-opacity)); } +.hover\:bg-blue-600:hover { + --tw-bg-opacity: 1; + background-color: rgb(37 99 235 / var(--tw-bg-opacity)); +} + .hover\:bg-blue-700:hover { --tw-bg-opacity: 1; background-color: rgb(29 78 216 / var(--tw-bg-opacity)); @@ -1584,6 +1676,11 @@ body.dark-mode { background-color: rgb(22 163 74 / var(--tw-bg-opacity)); } +.hover\:bg-indigo-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(238 242 255 / var(--tw-bg-opacity)); +} + .hover\:bg-indigo-600:hover { --tw-bg-opacity: 1; background-color: rgb(79 70 229 / var(--tw-bg-opacity)); @@ -1619,6 +1716,11 @@ body.dark-mode { background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.hover\:bg-indigo-900:hover { + --tw-bg-opacity: 1; + background-color: rgb(49 46 129 / var(--tw-bg-opacity)); +} + .hover\:text-blue-700:hover { --tw-text-opacity: 1; color: rgb(29 78 216 / var(--tw-text-opacity)); @@ -1658,6 +1760,12 @@ body.dark-mode { text-decoration-line: underline; } +.hover\:shadow-xl:hover { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + .hover\:shadow-gray-300:hover { --tw-shadow-color: #d1d5db; --tw-shadow: var(--tw-shadow-colored); @@ -1668,6 +1776,11 @@ body.dark-mode { --tw-shadow: var(--tw-shadow-colored); } +.focus\:border-blue-500:focus { + --tw-border-opacity: 1; + border-color: rgb(59 130 246 / var(--tw-border-opacity)); +} + .focus\:border-indigo-300:focus { --tw-border-opacity: 1; border-color: rgb(165 180 252 / var(--tw-border-opacity)); @@ -1887,6 +2000,11 @@ body.dark-mode { color: rgb(253 224 71 / var(--tw-text-opacity)); } +.dark\:text-gray-500:is(.dark *) { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + .dark\:shadow-gray-800\/30:is(.dark *) { --tw-shadow-color: rgb(31 41 55 / 0.3); --tw-shadow: var(--tw-shadow-colored); @@ -2073,9 +2191,22 @@ body.dark-mode { } @media (min-width: 1024px) { + .lg\:w-1\/3 { + width: 33.333333%; + } + .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } + + .lg\:flex-row { + flex-direction: row; + } + + .lg\:px-20 { + padding-left: 5rem; + padding-right: 5rem; + } } .rtl\:space-x-reverse:where([dir="rtl"], [dir="rtl"] *) > :not([hidden]) ~ :not([hidden]) { diff --git a/frontend/src/utils/router.js b/frontend/src/utils/router.js index 038232a..b1f0a06 100644 --- a/frontend/src/utils/router.js +++ b/frontend/src/utils/router.js @@ -9,6 +9,7 @@ import { renderProfilePage } from '../pages/BloggerProfile.js'; import { renderFullBlogPost } from '../pages/ReadMoreBlog.js'; import { renderTermsOfUse } from '../pages/TermsOfUse.js'; import { renderDiscussionForum } from '../pages/DiscussionForum.js'; +import { renderStories } from '../pages/Stories.js'; const routes = { '/': renderHome, @@ -22,6 +23,7 @@ const routes = { '/discussion': renderDiscussionForum, '/readmore': renderFullBlogPost, '/termsOfUse': renderTermsOfUse, + '/stories': renderStories, }; export function router() {