diff --git a/src/main/java/polish_community_group_11/polish_community/security/WebSecurityConfig.java b/src/main/java/polish_community_group_11/polish_community/security/WebSecurityConfig.java index 3119b99b7968d0bfe754d5a243c95d251d938388..3b5e40a5b77ec2c801786878d75d1f791a8608e0 100644 --- a/src/main/java/polish_community_group_11/polish_community/security/WebSecurityConfig.java +++ b/src/main/java/polish_community_group_11/polish_community/security/WebSecurityConfig.java @@ -37,7 +37,7 @@ public class WebSecurityConfig { private final String[] whiteListingPath = { // "/event", // "event/*" -// "/api/feed/**" , + "/feed" }; public WebSecurityConfig(UserService userService, RoleService roleService) { diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 439ca31f77ddffe56e637f61db79e9f2373ef918..775be7cd3391a896d9a8914df8399555286351ef 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -83,10 +83,16 @@ INSERT INTO user_roles (user_id, role_id) VALUES (1, 1); -- Insert posts +-- INSERT INTO feed (post_image_url, post_title, post_description, post_time, user_id) VALUES +-- ('uploads/36b2c38d-c9d5-4e14-a433-895a565d3abf_steve-johnson-D7AuHpLxLPA-unsplash.jpg', 'Dynamic Art', '', '2024-12-07', 1), +-- ('uploads/5720f047-a3ca-4d4e-ab20-343aae7cc485_premium_photo-1733514691627-e62171fc052c.avif', 'Pots', 'Description for post 2', '2024-12-07', 2), +-- ('uploads/d0753820-30b3-429c-92c4-d82c910ba083_nicolas-jehly-0UU9-_1EMvM-unsplash.jpg', 'Beach Day', 'Description for post 3', '2024-12-07', 3); + INSERT INTO feed (post_image_url, post_title, post_description, post_time, user_id) VALUES - ('uploads/36b2c38d-c9d5-4e14-a433-895a565d3abf_steve-johnson-D7AuHpLxLPA-unsplash.jpg', 'Post 1', 'Description for post 1', '2024-12-07', 1), - ('uploads/5720f047-a3ca-4d4e-ab20-343aae7cc485_premium_photo-1733514691627-e62171fc052c.avif', 'Post 2', 'Description for post 2', '2024-12-07', 2), - ('uploads/d0753820-30b3-429c-92c4-d82c910ba083_nicolas-jehly-0UU9-_1EMvM-unsplash.jpg', 'Post 3', 'Description for post 3', '2024-12-07', 3); +('uploads/36b2c38d-c9d5-4e14-a433-895a565d3abf_steve-johnson-D7AuHpLxLPA-unsplash.jpg', 'Dynamic Art', 'A captivating blend of colors and shapes, showcasing modern artistic expression.', '2024-12-07', 1), +('uploads/5720f047-a3ca-4d4e-ab20-343aae7cc485_premium_photo-1733514691627-e62171fc052c.avif', 'Pots', 'Description for post 2', '2024-12-07', 2), +('uploads/d0753820-30b3-429c-92c4-d82c910ba083_nicolas-jehly-0UU9-_1EMvM-unsplash.jpg', 'Beach Day', 'Description for post 3', '2024-12-07', 3); + -- Insert tags INSERT INTO tags (tag_name) VALUES @@ -111,29 +117,71 @@ INSERT INTO post_likes (post_id, user_id) VALUES (2, 2), (2, 4); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) -values ('Science Fair', 'Students explore through the science fair', 'Cardiff', current_date,current_time, 1, 'https://marketplace.canva.com/EAE53TNAVD8/1/0/1131w/canva-event-present-science-fair-promotion-poster-1abqT-GiCNQ.jpg','Participating in the Science Fair offers you a unique opportunity to dive deep into the world of science, innovation, and discovery. Whether you''re a student eager to showcase your scientific knowledge or an individual with a passion for learning, this event is the perfect platform to fuel your curiosity. Here’s why you should join: -Engage with Innovative Ideas: Explore cutting-edge scientific projects that challenge the status quo and inspire new ways of thinking. -Collaborate with Like-Minded Individuals: Meet fellow science enthusiasts, students, and professionals who share your interests and passion for discovery. -Boost Your Critical Thinking: Through the process of research, experimentation, and presentation, you’ll develop critical problem-solving skills that are invaluable in any field. -Expand Your Knowledge: Learn about new technologies, scientific theories, and groundbreaking advancements that will shape the future of science and innovation. -Be a Part of a Larger Community: Join a global community of science advocates and future scientists, making valuable connections that could open doors to future opportunities.', 'Hands-On Experience: Gain practical, hands-on experience in the scientific method, from research and hypothesis testing to data analysis and presentation. -Develop Presentation Skills: Sharpen your ability to communicate complex scientific concepts in an engaging and accessible way, an essential skill for any future career. -Exposure to Career Opportunities: Connect with professionals in science, education, and industry, opening up potential career pathways, internships, and scholarships. -Recognition and Prizes: Stand a chance to win awards and gain recognition for your hard work and creativity. Whether you’re awarded for your innovation, research, or presentation, your efforts will be acknowledged. -Confidence Building: Presenting your work to peers, teachers, and judges builds confidence in your abilities and boosts self-esteem, allowing you to grow as both a scientist and an individual. -Inspire Future Projects: Your participation could spark new ideas and motivate others to start their own scientific endeavors, contributing to a culture of curiosity and learning. -Stay Ahead of the Curve: By participating, you gain knowledge about the latest trends in science and technology, giving you an edge in academic and professional fields. -By joining this science fair, you are not only enriching your own learning experience but also contributing to a vibrant community of innovators and explorers.'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) -values ('Games Fair', 'Gamers explore through the game fair', 'Bristol', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/game-event-poster-template-c54aaeed440befaacf79e6dd35deb8f5_screen.jpg?ts=1486132851','Abc', 'Def'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) -values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682','Abc', 'Def'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) -values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) -values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) -values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); -insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) -values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts='); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) +-- values ('Science Fair', 'Students explore through the science fair', 'Cardiff', current_date,current_time, 1, 'https://marketplace.canva.com/EAE53TNAVD8/1/0/1131w/canva-event-present-science-fair-promotion-poster-1abqT-GiCNQ.jpg','Participating in the Science Fair offers you a unique opportunity to dive deep into the world of science, innovation, and discovery. Whether you''re a student eager to showcase your scientific knowledge or an individual with a passion for learning, this event is the perfect platform to fuel your curiosity. Here’s why you should join: +-- Engage with Innovative Ideas: Explore cutting-edge scientific projects that challenge the status quo and inspire new ways of thinking. +-- Collaborate with Like-Minded Individuals: Meet fellow science enthusiasts, students, and professionals who share your interests and passion for discovery. +-- Boost Your Critical Thinking: Through the process of research, experimentation, and presentation, you’ll develop critical problem-solving skills that are invaluable in any field. +-- Expand Your Knowledge: Learn about new technologies, scientific theories, and groundbreaking advancements that will shape the future of science and innovation. +-- Be a Part of a Larger Community: Join a global community of science advocates and future scientists, making valuable connections that could open doors to future opportunities.', 'Hands-On Experience: Gain practical, hands-on experience in the scientific method, from research and hypothesis testing to data analysis and presentation. +-- Develop Presentation Skills: Sharpen your ability to communicate complex scientific concepts in an engaging and accessible way, an essential skill for any future career. +-- Exposure to Career Opportunities: Connect with professionals in science, education, and industry, opening up potential career pathways, internships, and scholarships. +-- Recognition and Prizes: Stand a chance to win awards and gain recognition for your hard work and creativity. Whether you’re awarded for your innovation, research, or presentation, your efforts will be acknowledged. +-- Confidence Building: Presenting your work to peers, teachers, and judges builds confidence in your abilities and boosts self-esteem, allowing you to grow as both a scientist and an individual. +-- Inspire Future Projects: Your participation could spark new ideas and motivate others to start their own scientific endeavors, contributing to a culture of curiosity and learning. +-- Stay Ahead of the Curve: By participating, you gain knowledge about the latest trends in science and technology, giving you an edge in academic and professional fields. +-- By joining this science fair, you are not only enriching your own learning experience but also contributing to a vibrant community of innovators and explorers.'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) +-- values ('Games Fair', 'Gamers explore through the game fair', 'Bristol', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/game-event-poster-template-c54aaeed440befaacf79e6dd35deb8f5_screen.jpg?ts=1486132851','Abc', 'Def'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url,whyJoin,benefits) +-- values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682','Abc', 'Def'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) +-- values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) +-- values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) +-- values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts=1637012682'); +-- insert into event (event_title, event_description, location, event_date, event_time,user_id, event_poster_url) +-- values ('Bikes Fair', 'Riders explore through the Ride fair', 'Newport', current_date,current_time, 1, 'https://d1csarkz8obe9u.cloudfront.net/posterpreviews/bike-fest-poster-design-template-fb1cc1ab4b2aee783f8ee75476c4c92d_screen.jpg?ts='); + +INSERT INTO event (event_title, event_description, location, event_date, event_time, user_id, event_poster_url, whyJoin, benefits) +VALUES + ('Polish Cultural Festival', + 'A celebration of Polish traditions, music, and cuisine. Experience the rich cultural heritage of Poland in an engaging and festive environment.', + 'Cardiff', + '2025-03-15', + '15:00', + 1, + 'https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/462f4808-8ae9-43e6-95b3-d74452c13685/czajkowski-1wystawa.jpg', + 'Celebrate Polish traditions with a diverse group of people who share a passion for Polish heritage. Enjoy delicious food, music, and traditional dances.', + 'Cultural exchange, networking, and a memorable experience filled with entertainment and learning.'), + + ('Polish Film Night', + 'Watch iconic Polish films and discuss the cultural and artistic elements behind them.', + 'Bristol', + '2025-04-20', + '18:30', + 1, + 'https://images.squarespace-cdn.com/content/v1/5bd8e569506fbe6dc72c84b9/1579304578492-7QC023N2JJCNACZ949YV/LADY%2BSTICKING%2BUP%2BPOSTERS.jpg?format=2500w', + 'Join to explore the depth of Polish cinema, understand cultural narratives, and enjoy a night of artistic storytelling.', + 'Inspiration from masterpieces, networking with film enthusiasts, and an engaging cultural experience.'), + + ('Polish History Exhibition', + 'An exhibition showcasing Poland’s historical journey, including artifacts, photographs, and stories.', + 'Newport', + '2025-05-05', + '10:00', + 1, + 'https://images.unsplash.com/photo-1473163928189-364b2c4e1135?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + 'Dive into the fascinating history of Poland and understand its influence on the world.', + 'Gain historical insights, appreciation for heritage, and connect with like-minded history enthusiasts.'), + + ('Traditional Polish Cooking Workshop', + 'Learn to cook authentic Polish dishes like pierogi and bigos with expert chefs.', + 'Swansea', + '2025-06-12', + '14:00', + 1, + 'https://plus.unsplash.com/premium_photo-1691837115446-51a333c1941b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D', + 'Join this hands-on workshop to master traditional Polish recipes and enjoy a fun culinary experience.', + 'Learn new cooking skills, enjoy delicious food, and make new friends who share your passion for Polish cuisine.') diff --git a/src/main/resources/static/css/contact/contact.css b/src/main/resources/static/css/contact/contact.css index 8ee14877241316282d20e2150c5065e9892c3bf2..abd0f921b9400f207dbe7331abc9c42a9a5d0ba0 100644 --- a/src/main/resources/static/css/contact/contact.css +++ b/src/main/resources/static/css/contact/contact.css @@ -3,13 +3,11 @@ body { margin: 0; padding: 0; box-sizing: border-box; - background-color: #f4f4f9; font-family: Arial, sans-serif; padding-top: 80px; } #title{ - color: black; text-align: center; font-size: 35px; @@ -28,6 +26,9 @@ body { /* FAQ Section */ #faq { padding: 20px; + display: flex; + flex-direction: column; + align-items: center; } .faq-question { diff --git a/src/main/resources/static/css/headings/headings.css b/src/main/resources/static/css/headings/headings.css index 547d068352bfa01d97e645c8d7e79d2b32e5ab71..0a6bf08ecc08d3ee1d97546675c96e05e37863b3 100644 --- a/src/main/resources/static/css/headings/headings.css +++ b/src/main/resources/static/css/headings/headings.css @@ -49,7 +49,7 @@ button { .list-item{ background-color: var(--secondary-color); - padding: 20px 10px; + padding: 20px 20px; border-left: 4px solid var(--primary-color); display: flex; flex-direction: column; @@ -62,6 +62,11 @@ button { font-weight: 450; } +.list-item > p { + color: var(--secondary-text-color); + font-size: 14px; +} + .list-item:hover { border-left: 4px solid var(--tertiary-color); } diff --git a/src/main/resources/static/css/home/home.css b/src/main/resources/static/css/home/home.css index 1694ebbdf2ebaf8a8729a7c1315737c4e3322c58..b46b104575eadcda03983cfa1b6a1a6b0103dae6 100644 --- a/src/main/resources/static/css/home/home.css +++ b/src/main/resources/static/css/home/home.css @@ -4,6 +4,7 @@ section { display: flex; flex-direction: column; align-items: center; + margin-bottom: 30px; } @@ -55,6 +56,7 @@ button:hover { display: flex; flex-direction: column; justify-content: space-between; /* Space out the content inside the tile */ + transition:transform ease-in-out; } /* Logo and title container */ @@ -97,8 +99,12 @@ button:hover { height: 100%; /* Ensures the link takes full height of the tile */ } +.tile:hover{ + transform: scale(1.03); +} + .tileLink:hover { - background-color: #f0f0f0; /* Light background on hover */ + /*background-color: #f0f0f0; !* Light background on hover *!*/ border-radius: 10px; transition: background-color 0.3s ease; } diff --git a/src/main/resources/static/css/information/infoStyles.css b/src/main/resources/static/css/information/infoStyles.css index 90202542e152c378d66fd96c922ca57d0c942ea6..6664154b3d0d82d936883e7e27a98242c81f98f9 100644 --- a/src/main/resources/static/css/information/infoStyles.css +++ b/src/main/resources/static/css/information/infoStyles.css @@ -1,7 +1,5 @@ *{ box-sizing: border-box; - font-family: "Roboto", serif; - /*font-family:'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif*/ } diff --git a/src/main/resources/static/css/layout/layout.css b/src/main/resources/static/css/layout/layout.css index d5e14947d5224ce34fc41ecd7de8620af43363bb..8007843d0c139c520ea086c0231d4206b81a3f3b 100644 --- a/src/main/resources/static/css/layout/layout.css +++ b/src/main/resources/static/css/layout/layout.css @@ -221,6 +221,10 @@ nav.sidebar { /* ACCOUNT OPTIONS STYLING */ /* Dropdown styles */ +#account-options { + cursor: pointer; +} + .dropdown { position: relative; display: inline-block; @@ -230,9 +234,11 @@ nav.sidebar { display: none; position: absolute; background-color: #f9f9f9; - min-width: 160px; + min-width: 100px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; + right: 50px; + top: 60px; } .dropdown-content a { @@ -250,5 +256,9 @@ nav.sidebar { display: block; } +.proficon { + width: 20px; + height: 20px; +} /* ACCOUNT OPTIONS STYLING END */ \ No newline at end of file diff --git a/src/main/resources/static/css/news/editNewsStyle.css b/src/main/resources/static/css/news/editNewsStyle.css index 0b575d42276f870de0cd3951de929305e89ca890..cc837a082563098a28f4d6af79eab7a41b95456a 100644 --- a/src/main/resources/static/css/news/editNewsStyle.css +++ b/src/main/resources/static/css/news/editNewsStyle.css @@ -1,3 +1,14 @@ +.edit-news-page > h1 { + text-align: center; +} + +.edit-news-page { + padding: 30px; + display: flex; + align-items: center; + flex-direction: column; +} + .form-container { display: flex; justify-content: center; @@ -10,19 +21,18 @@ form { background-color: white; border-radius: 10px; - padding: 30px; - width: 500px; - max-width: 100%; + width: 80%; box-sizing: border-box; - margin: auto; } h1 { - text-align: left; - margin-bottom: 20px; + text-align: center; + padding: 10px; + font-size: 32px; } + label { display: block; font-weight: bold; diff --git a/src/main/resources/static/css/register/register.css b/src/main/resources/static/css/register/register.css index fce9b8317fa68725866157c3baa1d42ed818a9b4..c22230e171a87a62379f4aa2d52b101dd63a6065 100644 --- a/src/main/resources/static/css/register/register.css +++ b/src/main/resources/static/css/register/register.css @@ -1,14 +1,11 @@ /* General Styles */ -body { - font-family: Arial, sans-serif; - background-color: #f9f9f9; - margin: 0; +section { padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; - height: 100vh; + margin-bottom: 30px; } /* Title */ diff --git a/src/main/resources/static/js/headings/headings.js b/src/main/resources/static/js/headings/headings.js index 4c439b16623d49f1a59e8d4c4784567060899159..1e3cd429dc7c996a6e9b69b2f460e47bb4ffad01 100644 --- a/src/main/resources/static/js/headings/headings.js +++ b/src/main/resources/static/js/headings/headings.js @@ -1,11 +1,24 @@ // get category from url params const urlParams = new URLSearchParams(window.location.search); const categoryId = window.location.pathname.split('/')[2]; // Assuming /categories/{id} -const categoryName = urlParams.get('categoryName'); +let categoryName = ""; // fetch category headings from api const apiUrl = '/getInfoByCategoryId'; +async function getCategoryName(){ + try{ + const response = await fetch(`/api/categories/${categoryId}`) + if (!response.ok) throw new Error (`Http error! status: ${response.status}`) + + const category = await response.json() + categoryName = category.categoryTitle; + console.log('Category Name:', categoryName); + } catch (error) { + console.error('Error fetching category', error); + } +} + async function fetchCategoryHeadings() { try { const response = await fetch(`${apiUrl}/${categoryId}`); @@ -33,8 +46,8 @@ function renderHeadings(headings) { const title = document.createElement('h2') title.innerHTML = `<i class="bi bi-file-earmark-text"></i> ${heading.infoTitle} ` - // const description = document.createElement('p'); - // description.textContent = heading.description + const shortDesc = document.createElement(`p`) + shortDesc.textContent = `${heading.shortDescription}` const link = document.createElement('a') link.href = `/info/${heading.informationId}`; @@ -47,144 +60,147 @@ function renderHeadings(headings) { link.appendChild(readMore); listItem.appendChild(title) - // listItem.appendChild(description) + listItem.appendChild(shortDesc); listItem.appendChild(link) container.appendChild(listItem) }); } -// change the title of the page bases on category -document.getElementById('category-name').textContent = categoryName ? `${categoryName}` : 'Category Name Not Found'; - -// Fetch and render the category headings when the page loads -fetchCategoryHeadings(); - - -// Get the category id from the url -function getCategoryIdFromUrl() { - const path = window.location.pathname; - const parts = path.split("/"); - return parts[2]; -} - -// Function to dynamically add href url to add information button -function generateAddInfoPageUrl() { - // Extract categoryId from the URL - const categoryId = getCategoryIdFromUrl(); +async function init() { + await getCategoryName(); + // change the title of the page based on category + document.getElementById('category-name').textContent = categoryName ? `${categoryName}` : 'Category Name Not Found'; - // Create url from category id - const url = `/info/add/${categoryId}`; - const link = document.getElementById("addInfo"); - link.setAttribute("href", url); -} + // Fetch and render the category headings when the page loads + fetchCategoryHeadings(); -generateAddInfoPageUrl(); + // Get the category id from the url + function getCategoryIdFromUrl() { + const path = window.location.pathname; + const parts = path.split("/"); + return parts[2]; + } + // Function to dynamically add href url to add information button + function generateAddInfoPageUrl() { + // Extract categoryId from the URL + const categoryId = getCategoryIdFromUrl(); -// Function to toggle edit mode to enable multi-select for deletion -function toggleEditMode() { - const container = document.getElementById('headings-container'); - const editButton = document.getElementById('edit-mode-button'); - const deleteButton = document.getElementById('delete-button'); - const isEditMode = container.classList.toggle('edit-mode'); - - const listItems = container.querySelectorAll('.list-item'); - - if (isEditMode) { - // Add checkboxes to each heading list item - listItems.forEach(item => { - if (!item.querySelector('input[type="checkbox"]')) { - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - checkbox.classList.add('multi-select-checkbox'); - checkbox.addEventListener('change', toggleDeleteButtonState); - - // Inserts the checkbox before the first child of the list item - item.insertBefore(checkbox, item.firstChild); - } - }); - editButton.textContent = 'Done'; - // Enable the delete button - deleteButton.disabled = false; - deleteButton.style.visibility="visible" - } else { - // Remove checkboxes from each list item - listItems.forEach(item => { - const checkbox = item.querySelector('.multi-select-checkbox'); - if (checkbox) { - item.removeChild(checkbox); - } - }); - editButton.textContent = 'Edit'; - // Disables and hides the delete button - deleteButton.disabled = true; - deleteButton.style.visibility="hidden" + // Create url from category id + const url = `/info/add/${categoryId}`; + const link = document.getElementById("addInfo"); + link.setAttribute("href", url); } -} - -// Function to toggle the delete button state based on checkbox selection -function toggleDeleteButtonState() { - const selectedItems = document.querySelectorAll('.multi-select-checkbox:checked'); - const deleteButton = document.getElementById('delete-button'); - deleteButton.disabled = selectedItems.length === 0; -} -// Function to delete selected items -async function deleteSelectedItems() { - const selectedItems = document.querySelectorAll('.multi-select-checkbox:checked'); - - // Get the list of heading ids to be deleted - const idsToDelete = Array.from(selectedItems).map(checkbox => { - const listItem = checkbox.closest('.list-item'); - const anchor = listItem.querySelector('a.heading-link'); - if (anchor) { - const href = anchor.getAttribute('href'); - const idMatch = href.match(/info\/(\d+)/); // Extract the ID using regex - return idMatch ? idMatch[1] : null; // Return the ID if matched + generateAddInfoPageUrl(); + + // Function to toggle edit mode to enable multi-select for deletion + function toggleEditMode() { + const container = document.getElementById('headings-container'); + const editButton = document.getElementById('edit-mode-button'); + const deleteButton = document.getElementById('delete-button'); + const isEditMode = container.classList.toggle('edit-mode'); + + const listItems = container.querySelectorAll('.list-item'); + + if (isEditMode) { + // Add checkboxes to each heading list item + listItems.forEach(item => { + if (!item.querySelector('input[type="checkbox"]')) { + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.classList.add('multi-select-checkbox'); + checkbox.addEventListener('change', toggleDeleteButtonState); + + // Inserts the checkbox before the first child of the list item + item.insertBefore(checkbox, item.firstChild); + } + }); + editButton.textContent = 'Done'; + // Enable the delete button + deleteButton.disabled = false; + deleteButton.style.visibility="visible" + } else { + // Remove checkboxes from each list item + listItems.forEach(item => { + const checkbox = item.querySelector('.multi-select-checkbox'); + if (checkbox) { + item.removeChild(checkbox); + } + }); + editButton.textContent = 'Edit'; + // Disables and hides the delete button + deleteButton.disabled = true; + deleteButton.style.visibility="hidden" } - return null; // Skip if no anchor element or invalid format - }).filter(id => id !== null); + } - if (idsToDelete.length === 0) { - alert("No headings selected for deletion."); - return; + // Function to toggle the delete button state based on checkbox selection + function toggleDeleteButtonState() { + const selectedItems = document.querySelectorAll('.multi-select-checkbox:checked'); + const deleteButton = document.getElementById('delete-button'); + deleteButton.disabled = selectedItems.length === 0; } - // Check confirmation before deletion - const confirmed = confirm("Are you sure you want to delete the selected list of headings?"); - if (!confirmed) return; + // Function to delete selected items + async function deleteSelectedItems() { + const selectedItems = document.querySelectorAll('.multi-select-checkbox:checked'); - // Convert array of heading IDs to a comma-separated string to be passed as a parameter - const idList = idsToDelete.join(','); + // Get the list of heading ids to be deleted + const idsToDelete = Array.from(selectedItems).map(checkbox => { + const listItem = checkbox.closest('.list-item'); + const anchor = listItem.querySelector('a.heading-link'); + if (anchor) { + const href = anchor.getAttribute('href'); + const idMatch = href.match(/info\/(\d+)/); // Extract the ID using regex + return idMatch ? idMatch[1] : null; // Return the ID if matched + } + return null; // Skip if no anchor element or invalid format + }).filter(id => id !== null); - // Fetch api call to delete the list of headings at server side - try { - const response = await fetch('/api/info/delete', { - method: 'DELETE', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: `deleteIdList=${encodeURIComponent(idList)}` - }); - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + if (idsToDelete.length === 0) { + alert("No headings selected for deletion."); + return; } - // Remove deleted items from the DOM - selectedItems.forEach(checkbox => { - const listItem = checkbox.closest('.list-item'); - listItem.remove(); - }); + // Check confirmation before deletion + const confirmed = confirm("Are you sure you want to delete the selected list of headings?"); + if (!confirmed) return; + + // Convert array of heading IDs to a comma-separated string to be passed as a parameter + const idList = idsToDelete.join(','); + + // Fetch api call to delete the list of headings at server side + try { + const response = await fetch('/api/info/delete', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: `deleteIdList=${encodeURIComponent(idList)}` + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } - alert("Items deleted successfully."); + // Remove deleted items from the DOM + selectedItems.forEach(checkbox => { + const listItem = checkbox.closest('.list-item'); + listItem.remove(); + }); - } catch (error) { - console.error("Error deleting items:", error); - alert("Failed to delete items. Please try again."); + alert("Items deleted successfully."); + + } catch (error) { + console.error("Error deleting items:", error); + alert("Failed to delete items. Please try again."); + } } + + // Attach event listeners to toggle edit button and perform deletion + document.getElementById('edit-mode-button').addEventListener('click', toggleEditMode); + document.getElementById('delete-button').addEventListener('click', deleteSelectedItems); } -// Attach event listeners to toggle edit button and perform deletion -document.getElementById('edit-mode-button').addEventListener('click', toggleEditMode); -document.getElementById('delete-button').addEventListener('click', deleteSelectedItems); \ No newline at end of file +init(); diff --git a/src/main/resources/templates/categories/categories.html b/src/main/resources/templates/categories/categories.html index 8a4e5917e918dd1dd2650944b8dcde296f475094..2172142e1270a028988f88629dcdb0e1aa1365bc 100644 --- a/src/main/resources/templates/categories/categories.html +++ b/src/main/resources/templates/categories/categories.html @@ -1,7 +1,9 @@ <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> > <head> <title>Categories</title> @@ -11,7 +13,7 @@ <section class="info-database" layout:fragment="content" > <div class="title-section"> <h1>Community Information Database</h1> - <button id="add-new-category"> + <button id="add-new-category" sec:authorize="isAuthenticated()"> <i class="bi bi-folder-plus"></i> New Category </button> diff --git a/src/main/resources/templates/event/event.html b/src/main/resources/templates/event/event.html index c4e3731ac6202bb777f5f59c9b499864661a5657..ca7d771d1c0f37da90cc47b1834cc1d207a3e648 100644 --- a/src/main/resources/templates/event/event.html +++ b/src/main/resources/templates/event/event.html @@ -1,7 +1,9 @@ <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @@ -12,7 +14,7 @@ <div id="event-details" class="event-details"> <div class="general-headings-layout"> <h1>Community Events</h1> - <a th:href="@{event/add}"><button class="add-event-button">Add Event</button></a> + <a th:href="@{event/add}"><button class="add-event-button" sec:authorize="isAuthenticated()" >Add Event</button></a> </div> <div class="event-grid"> <!-- Loop through each event and create a clickable link --> @@ -28,9 +30,9 @@ <p><strong>Location:</strong> <span th:text="${event.getLocation()}">Event location</span></p> </a> </div> - <div class ="event-card-button"> + <div class ="event-card-button" sec:authorize="isAuthenticated()"> <button class="register-button">Register Now</button> - <a th:href="@{/event/edit/{id}(id=${event.getEvent_id()})}" class="event-link"><button>Edit Event</button></a> + <a th:href="@{/event/edit/{id}(id=${event.getEvent_id()})}" class="event-link" ><button>Edit Event</button></a> </div> </div> </div> diff --git a/src/main/resources/templates/feed/feed.html b/src/main/resources/templates/feed/feed.html index 058d86c2839162c3036e38cca1d1b74d172ae8cb..84778d0321f96e926c2ab8809190dadb77ee360e 100644 --- a/src/main/resources/templates/feed/feed.html +++ b/src/main/resources/templates/feed/feed.html @@ -2,7 +2,9 @@ <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @@ -19,7 +21,7 @@ <!-- posts will appear here --> <div id="postFeed" class="post-feed"> <!-- using template since I want to use it in javascript --> - <template id="post-template"> + <template id="post-template" > <div class="post"> <div class="post-header"> <div class="author-details"> @@ -71,7 +73,7 @@ </template> </div> - <button class="add-post" id="add-post"> + <button class="add-post" id="add-post" > <i class="bi bi-plus"></i> </button> <div id="create-new-modal" class="create-new-modal"> diff --git a/src/main/resources/templates/headings/headings.html b/src/main/resources/templates/headings/headings.html index 80cf562f5e032c351038c644a6f272581870b88c..c4b59610ebbe8b344c357d800ae7a9bfa63ea6b0 100644 --- a/src/main/resources/templates/headings/headings.html +++ b/src/main/resources/templates/headings/headings.html @@ -1,6 +1,8 @@ <!DOCTYPE html> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> <head> <title>Category Headings</title> <link rel="stylesheet" href="/css/headings/headings.css"> @@ -15,9 +17,9 @@ <div class="buttons"> <button id="delete-button" disabled>Delete</button> - <button id="edit-mode-button">Edit</button> + <button id="edit-mode-button" sec:authorize="isAuthenticated()" >Edit</button> <a id="addInfo"> - <button id="add-new-information"> + <button id="add-new-information" sec:authorize="isAuthenticated()" > <i class="bi bi-folder-plus"></i> New Information </button> diff --git a/src/main/resources/templates/information/information.html b/src/main/resources/templates/information/information.html index 37c2ee57f7161670c274485e27b0052b9d992e55..557dc108d20b4079cac8ca4fbd148121b6625cd1 100644 --- a/src/main/resources/templates/information/information.html +++ b/src/main/resources/templates/information/information.html @@ -1,6 +1,8 @@ <!DOCTYPE html> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> <head> <meta charset="UTF-8"> <!--Custom styles--> @@ -24,7 +26,7 @@ <h1 th:text="${selectedInfo.getInfoTitle()}">Information Title</h1> </section> <aside class="sub-head-edit-container"> - <a id="editButtonLink" th:href="@{/info/edit/{id} (id=${selectedInfo.getInformationId()})}"> + <a id="editButtonLink" th:href="@{/info/edit/{id} (id=${selectedInfo.getInformationId()})}" sec:authorize="isAuthenticated()" > <button><strong>Edit</strong></button></a> </aside> </section> diff --git a/src/main/resources/templates/layout/layout.html b/src/main/resources/templates/layout/layout.html index 829aeca235d83698170723c179cdbc3c662c0401..9e6bc8f74710eda31cef7b7fcd3ab82adca758c8 100644 --- a/src/main/resources/templates/layout/layout.html +++ b/src/main/resources/templates/layout/layout.html @@ -72,16 +72,16 @@ <!-- Profile --> <div id="account-options"> <div sec:authorize="isAnonymous()"> - <img src="/assets/navbarImages/profile.png" class="navIcons anonymous"> - <span class="navText">Sign in</span> + <img src="/assets/navbarImages/profile.png" class="navIcons anonymous proficon"> + <span class="navText" style="color: black">Sign in</span> <div class="dropdown-content"> <a class="dropdown-nav-link" th:href="@{/login}">Login</a> <a class="dropdown-nav-link" th:href="@{/register}">Sign up</a> </div> </div> <div sec:authorize="isAuthenticated()"> - <img src="/assets/navbarImages/profile.png" class="navIcons authenticated"> - <span class="navText"data-translate-key="navbar.profile">Profile</span> + <img src="/assets/navbarImages/profile.png" class="navIcons authenticated proficon"> + <span class="navText"data-translate-key="navbar.profile" style="color: black">Profile</span> <div class="dropdown-content"> <a class="navLink" th:href="@{/profile}">View profile</a> <a class="navLink" th:href="@{/logout}">Logout</a> @@ -124,10 +124,6 @@ <a href="#" class="social-icon"><img src="/assets/navbarImages/instagram.png" alt="Instagram"></a> </div> </div> - - <div class="footer-section copyright"> - <p class="footerCompanyName">© LUDEK PCG ltd. <span data-translate-key="footer.all_rights_reserved" >All rights reserved.</span></p> - </div> </footer> <script src="/js/layout/layout.js" defer></script> <script th:replace="~{comments/commentFragment::commentScript}"></script> diff --git a/src/main/resources/templates/news/editNews.html b/src/main/resources/templates/news/editNews.html index 9719d75d7d30f2fa5af6fcc0ca25f692b93cf017..6f19a254acf53ed8ba24975b99a7d4cd659439f7 100644 --- a/src/main/resources/templates/news/editNews.html +++ b/src/main/resources/templates/news/editNews.html @@ -1,5 +1,7 @@ <!DOCTYPE html> -<html lang="en"> +<html lang="en" xmlns:th="http://www.thymeleaf.org" + xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" + layout:decorate="~{layout/layout}"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @@ -8,7 +10,7 @@ <script src="/js/news/editNewsScript.js"></script> </head> -<body> +<section layout:fragment="content" class="edit-news-page"> <h1>Edit or Delete News</h1> <form th:action="@{/editNews/{id}(id=${news.news_id})}" th:object="${news}" method="post" onsubmit="return validateForm(event)"> <!-- Hidden field to hold the news ID --> @@ -66,6 +68,6 @@ </div> </form> -</body> +</section> </html> diff --git a/src/main/resources/templates/news/newsList.html b/src/main/resources/templates/news/newsList.html index 2e2a97ce2b01f99b9bfcedce8662a2fcab204ff6..bc226835b57afb4b9271d93852894f8a519028ec 100644 --- a/src/main/resources/templates/news/newsList.html +++ b/src/main/resources/templates/news/newsList.html @@ -1,6 +1,8 @@ <!DOCTYPE html> <html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" - layout:decorate="~{layout/layout}"> + layout:decorate="~{layout/layout}" + xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity6" +> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @@ -13,7 +15,7 @@ <section layout:fragment="content" class="content"> <div class="general-headings-layout"> <h1>Community News</h1> - <button onclick="openNewsForm()" id="openModalBtn" class="openModalBtn">Add News</button> + <button onclick="openNewsForm()" id="openModalBtn" class="openModalBtn" sec:authorize="isAuthenticated()" >Add News</button> </div> <main class="news-container"> <!-- Main news card --> @@ -29,7 +31,7 @@ </div> <div class="card-footer"> <p class="source">Source: <span th:text="${newsList[0].getNews_source()}"></span></p> - <a th:href="@{/editNews/{id}(id=${newsList[0].getNews_id()})}" class="modify-btn modify-link">Modify</a> + <a th:href="@{/editNews/{id}(id=${newsList[0].getNews_id()})}" class="modify-btn modify-link" sec:authorize="isAuthenticated()" >Modify</a> <p class="date" th:text="${newsList[0].getNews_upload_date()}"></p> </div> </div> @@ -42,7 +44,7 @@ <div class="card-footer"> <p class="source">Source: <span th:text="${news.getNews_source()}"></span></p> <p class="date" th:text="${news.getNews_upload_date()}"></p> - <a th:href="@{/editNews/{id}(id=${news.getNews_id()})}" class="modify-btn modify-link">Modify</a> + <a th:href="@{/editNews/{id}(id=${news.getNews_id()})}" class="modify-btn modify-link" sec:authorize="isAuthenticated()">Modify</a> </div> </div> </div> diff --git a/src/main/resources/templates/register/register.html b/src/main/resources/templates/register/register.html index 87bd84f6a24a084bbec0c49992132737da7a2924..930baf9e418088707ad4723e7c6927756c8544e7 100644 --- a/src/main/resources/templates/register/register.html +++ b/src/main/resources/templates/register/register.html @@ -9,10 +9,10 @@ <script src="/js/register/register.js" defer></script> </head> -<body> +<section layout:fragment="content"> <h1>Create an Account</h1> - - <div class="registerContainer" layout:fragment="content"> + + <div class="registerContainer" > <!-- The form is bound to the 'user' object --> <form th:action="@{/register}" th:method="post" th:object="${user}" class="registerForm"> @@ -37,7 +37,7 @@ <span id="strengthMessage"></span> </div> <span class="error"></span> - </div> + </div> <div class="registerField"> <label for="confirmPassword">Confirm Password</label> @@ -50,12 +50,13 @@ <input type="date" id="dob" name="dob" required> </div> - <div class="registerField"> - <label for="roleId">Role</label> - <select name="roleId"> - <option th:each="role : ${roles}" th:value="${role.id}" th:text="${role.name}"></option> - </select> - </div> +<!-- <div class="registerField">--> +<!-- <label for="roleId" >Role</label>--> +<!-- <select name="roleId">--> +<!-- <option th:each="role : ${roles}" th:value="${role.id}" th:text="${role.name}"></option>--> +<!-- </select>--> +<!-- </div>--> + <input type="hidden" name="roleId" value="1"> <div class="termsField"> <input type="checkbox" id="agreeTerms" required> @@ -71,9 +72,9 @@ <div class="alreadyAccount"> <p>Already have an account? <a th:href="@{/login}" class="loginLink">Log in here</a>.</p> </div> - + </form> - + </div> -</body> +</section> </html> diff --git a/uploads/344fa776-e64f-4e5a-9e17-a25d83d18bd3_md-shahjalal-jomodder-foTBpnC2Bvw-unsplash.jpg b/uploads/344fa776-e64f-4e5a-9e17-a25d83d18bd3_md-shahjalal-jomodder-foTBpnC2Bvw-unsplash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1929e46ff60d1a1578650f06c569bf7d0f7327e9 Binary files /dev/null and b/uploads/344fa776-e64f-4e5a-9e17-a25d83d18bd3_md-shahjalal-jomodder-foTBpnC2Bvw-unsplash.jpg differ