Table of Contents
Florin County Council community hub is a space that is; open and accessible to the local community; providing services that the local community wants and needs; where formal decisions about running and managing the hub are taken by people who come mainly from within the local community.
The aim of this project is to create a community website with the aim of allowing members & businesses in Florin County to:
- Post jobs/volunteering opportunities
- Reduce overflow in the local recycling centre by creating a marketplace for items that can be reused and read information on reusable products
- Post clubs and learning opportunities
- Post events
If you would like to see the code for yourself or run the client locally start by cloning the repository through the command line: git clone (`git@github.com:PiroAvni/Florin_County_Council_Client.git`)
.
Then with the IDE extension live server
you can run the client side directly from your browser localHost : http://localhost:3000/
To test, you will need to git clone the project and install package.json using Terminal.
Run in the Terminal:
npm install
To install the Jest package separately:
npm install --save-dev jest
To run the client you have two options:
- run live-server or
- directly open html file
To access the community site, please click on the link Live Site
To access the server side, please click on the link Server
To run the test, you will need to run npm run test
in the Terminal.
To get the test to run, a copy of the html file were created with the test files reference those files, the copied HTML files are using the following naming convention:
indexcopy.html
Laptop | Ipad |
---|---|
The technologies used to build the client:
Here you can find the Figma showing : WireFrames, Kanban and our Database ERD
- Combine and share ideas on potential features.
- Identify stakeholders - Stakeholder map
- Wireframes were made on Figma and had a color theme to work with
- Kanban broad was create to track out backlogs
- ERD for the database
- User Registration
- User Login
- Create Posts
- Delete Posts
- Selected Posts via category
- MarketPlace
- Search functionality
- Map GeoAlerts
- Business Location Search
- Alerts -Notifications - Bin collection
- Reporting - local issues
- Tours
- Local News updates
- Connectivity to IOT
- Advertising for local business
- Admin Section
- Business Section
- Making sure the random fetch was only called once so that the corresponding data related to the hints, fun facts, and multiple choice answers were linked (we wouldn't want them to be from different countries).
- Uploading post or category entries on load-up and having a button to pre select category entries.
- On the registry for both radio button to select Admin or Business, we have difficulties passing the value back to the database for authorization.
- Creating a function to to create HTML elements for the entries.
Code to create new Elements for each:
async function createPostElement(data) {
console.log(data);
const container = document.getElementById("post-list");
const post = document.createElement("div");
post.className = "post";
post.id = "card"
const header = document.createElement("h2");
// header.textContent = "Title:";
header.classList.add("m-2", "card-title");
header.textContent = data["title"];
post.appendChild(header);
const category = document.createElement("p");
category.classList.add("m-2", "card-subtitle");
category.textContent = data["category"];
post.appendChild(category);
const content = document.createElement("p");
content.classList.add("m-2", "card-text");
content.textContent = data["content"];
post.appendChild(content);
const date = document.createElement("p");
const dateTitle = document.createElement("p");
dateTitle.classList.add("date-format", "m-2");
dateTitle.textContent = "created:";
date.classList.add("date-format", "m-2");
const dateFormat = new Date(data["post_date"]).toDateString();
date.textContent = `Post Date: ${dateFormat}`;
post.appendChild(date);
const btnContainer = document.createElement("div");
btnContainer.className = "flex btn-container";
btnContainer.style.cssText ="display:flex, justify-content: space-between"
post.appendChild(btnContainer);
const commentBtn = document.createElement("div");
commentBtn.className = "btn", "m-1","w-75";
commentBtn.id = "btn-comment"
commentBtn.textContent = "Comments"
btnContainer.appendChild(commentBtn)
const deleteBtn = document.createElement("div");
deleteBtn.className = "btn btn-delete";
deleteBtn.id = "btn-delete"
deleteBtn.textContent = "Delete"
btnContainer.style.cssText ="justify-content: space-between"
btnContainer.appendChild(deleteBtn)
const comment = document.createElement("div");
comment.className = "comment";
comment.style.cssText ="display:flex, justify-content: space-between, margin:auto"
comment.id = `comment-container-${data["post_id"]}`
commentBtn.addEventListener('click', async (e) => {
e.preventDefault();
const commentData = await loadComments(data["id"])
console.log('line 54', commentData)
if (commentData.length !== 0 || commentData !== undefined) {
commentData.forEach((c) => {
const newComment = document.createElement('p');
console.log('line51', newComment)
newComment.textContent = c["comment"];
document.getElementById(`comment-container-${data["post_id"]}`).appendChild(newComment);
document.getElementById('commentBtn').disabled = true
})
}
})
The code to upload post / entries. When clicking on each service button it allowed to display an up-to date category for that particular service button. The loadPost function takes in the data, once it fetches the category based on the params, the code will then iterate through passing the data in to the createPostElements function to create the elements for each post.
async function loadPosts(category) {
const options = {
headers: {
Authorization: localStorage.getItem("token"),
},
};
const response = await fetch(
`https://florin-server-web.onrender.com/posts/${category}`,
options
);
console.log(response);
if (response.status == 200) {
const posts = await response.json();
posts.forEach((p) => {
createPostElement(p)
});
} else {
// window.location.assign("./login.js");
}
}
loadPosts('services');
// Service Buttons
document.getElementById("jobs-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("Jobs")
});
document.getElementById("voluntary-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("voluntary");
});
document.getElementById("events-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("events");
});
document.getElementById("announcements-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("announcements");
});
document.getElementById("announcements-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("announcements");
});
document.getElementById("clubs-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("clubs");
});
document.getElementById("services-btn").addEventListener("click", (e) => {
e.preventDefault();
const element = document.querySelectorAll(".post")
element.forEach(post =>{
console.log('1')
post.remove();
})
loadPosts("services");
});
- We completed a functional MVP.
- Challenges were dealt with.
Avni Piro (https://github.com/PiroAvni)
Christopher Sharpe (https://github.com/CingSharped)
Muhammad Yaaseen Rossan (https://github.com/yrossan)
MIT License: see the LICENSE
file.