Skip to content
Open

JS2 #309

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 80 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,80 @@
# css-frameworks-ca
Replace this text with a description of your social media project.
ChatterHub - A Social Media Platform Frontend

Project Overview

ChatterHub is a social media platform frontend built using HTML, CSS/SCSS, and JavaScript. The platform allows users to register, log in, and view a feed of posts retrieved from the Noroff API. Key features include user authentication, post management, and a visually structured content feed.

Features

• User Authentication
• Register with valid @noroff.no or @stud.noroff.no emails.
• Login functionality with secure token storage.
• Post Feed
• Displays posts fetched from the Noroff API in a responsive card grid.
• Pagination with a 9-post display limit.
• Fallback image for posts without media.

Getting Started

Prerequisites

• Visual Studio Code or any preferred IDE
• Basic understanding of JavaScript, HTML, and CSS
• API key from the Noroff API

Installation

1. Clone the repository:
git clone
cd chatterhub
2. Open in Visual Studio Code:
code .
3. Install Live Server for local development:
• Search for “Live Server” in the VSCode extensions tab and install it.

Usage

1. Start the project using Live Server.
2. Navigate to the following routes:
• login/index.html for login
• register/index.html for registration
• feed/index.html to view the post feed

Project Structure

chatterhub/
├── index.html # Home page
├── login/
│ └── index.html # Login page
├── register/
│ └── index.html # Registration page
├── feed/
│ └── index.html # Post feed page
├── src/ # Source files
│ └── scss/ # SCSS styles
├── scripts/ # JavaScript files
│ └── login.js # Login handling script
│ └── register.js # Registration script
│ └── posts.js # Post feed handling
└── images/ # Static images

API Integration

Noroff API

The application integrates with the Noroff API to fetch and display posts as well as handle user authentication. To access the API, make sure to use your valid API key and Authorization Bearer token.

Project Management

📌 Trello Board: [JavaScript 2 Course Assignment](https://trello.com/b/VYdUkY8J/javascript-2-course-assignment)

Development Notes

• SCSS files are precompiled for cleaner CSS management.
• Responsive Bootstrap grid is used for structured layout design.
• Authenticated routes require valid access tokens.

License

This project is licensed under the MIT License.
150 changes: 150 additions & 0 deletions feed/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatterHub - Profile</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/src/scss/index.css">
<link rel="icon" href="/images/C Logo.png" type="image/x-icon">
</head>
<body>
<!-- Header / Navbar -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<!-- Brand Logo/Name -->
<a class="navbar-brand" href="/feed/index.html">
<img src="/images/C Logo.png" width="50px" alt="ChatterHub Logo" class="d-inline-block align-text-center">
ChatterHub
</a>

<!-- Toggler for mobile view (hamburger menu) -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<!-- Navbar Links -->
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" href="/feed/index.html">Feed</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/profile/index.html">Profile</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Settings
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="/profile/index.html">Account Settings</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/index.html">Logout</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>

<div class="container auth-container">
<div class="row justify-content-center">
<div class="col-md-6">
<!-- Profile Header -->
<div class="auth-header">
<img src="/images/Default_pfp.svg.png" width="100px" alt="Profile Picture" class="mb-3 rounded-circle">
<div>Feed</div>
</div>

<!-- Search Bar -->
<div class="mb-4">
<input type="text" id="search-input" class="form-control" placeholder="Search posts..." aria-label="Search">
</div>

<!-- Sort Options -->
<div class="mb-4">
<select id="sort-filter" class="form-select">
<option value="newest" selected>Newest</option>
<option value="oldest">Oldest</option>
<option value="title-asc">Title (A-Z)</option>
<option value="title-desc">Title (Z-A)</option>
</select>
</div>

<!-- Create New Post Form -->
<div class="card mb-4">
<div class="card-body">
<h4 class="mb-3">Create a New Post</h4>
<form id="post-form" enctype="multipart/form-data">
<!-- Post Title -->
<div class="mb-3">
<label for="post-title" class="form-label">Post Title</label>
<input type="text" class="form-control" id="post-title" name="post-title" required>
</div>
<!-- Post Image URL -->
<div class="mb-3">
<label for="post-image-url" class="form-label">Post Image URL</label>
<input type="text" class="form-control" id="post-image-url" name="post-image-url" placeholder="https://url.com/image.jpg">
</div>
<!-- Post Content -->
<div class="mb-3">
<label for="post-content" class="form-label">Post Content</label>
<textarea class="form-control" id="post-content" name="post-content" rows="3" required></textarea>
</div>
<!-- Submit Button -->
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">Post</button>
</div>
</form>
</div>
</div>

<!-- Posts List -->
<h2 class="text-center">Posts</h2>
<div id="post-feed"></div>
</div>
</div>

<!-- Pagination (if needed) -->
<div id="pagination"></div>
</div>

<!-- Modal for Post Details -->
<div id="post-details-modal" class="modal fade" tabindex="-1" aria-labelledby="post-details-modal-label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="post-details-title"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img id="post-details-image" class="img-fluid mb-3" alt="Post Image"/>
<p id="post-details-body"></p>
<p id="post-details-created"></p>
<p id="post-details-tags"></p>
<p id="post-details-author"></p>
<div id="error-message" class="alert alert-danger d-none"></div> <!-- Error message for edit/delete -->
<button id="edit-post" class="btn btn-warning">Edit</button>
<button id="delete-post" class="btn btn-danger">Delete</button>
</div>
</div>
</div>
</div>

<footer class="footer">
<div class="footer-links">
<a href="#">Privacy Policy</a>
<a href="#">Terms of Service</a>
</div>
</footer>

<!-- Get Posts Script -->
<script src="/scripts/posts.js"></script>

<!-- Popper.js (for Bootstrap) -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>
</body>
</html>
Binary file added images/C Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Default_pfp.svg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/default_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 96 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatterHub - Login or Register</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="src/scss/index.css">
<link rel="icon" href="/images/C Logo.png" type="image/x-icon">

</head>
<body>
<!-- Header / Navbar -->
<div class="container auth-container">
<div class="row justify-content-center">
<div class="col-md-6">
<!-- Logo / Branding -->
<div class="auth-header">
<img src="/images/C Logo.png" width="250px" alt="ChatterHub Logo" class="mb-3">
<div>Welcome to ChatterHub</div>
</div>
<!-- Tagline -->
<p class="tagline">Connect with your friends and the world around you.</p>
<!-- Card for Authentication -->
<div class="card">
<div class="card-body">
<h4 class="text-center mb-4">Login</h4>
<!-- Authentication Form with 'needs-validation' class added -->
<form id="auth-form" class="needs-validation" novalidate>
<!-- Username -->
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" required>
<div class="invalid-feedback">
Please enter an email.
</div>
</div>
<!-- Password -->
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required minlength="8">
<div class="invalid-feedback">
Password must be at least 8 characters long.
</div>
</div>
<!-- Login/Register Button -->
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary">Login</button>
<button type="button" class="btn btn-outline-secondary" id="register-btn">Register</button>
</div>
</form>
<!-- Error message placed inside the form -->
<p id="error-message" class="text-danger mt-2"></p>
</div>
</div>
<!-- Footer Links -->
<div class="footer-links">
<a href="#">Privacy Policy</a> |
<a href="#">Terms of Service</a>
</div>
</div>
</div>
</div>

<!-- Bootstrap JS and Popper.js -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>

<!-- script.js -->
<script src="scripts/login.js"></script>

<!-- Register Button Navigation Script -->
<script>
document.getElementById('register-btn').addEventListener('click', function() {
window.location.href = 'register/index.html'; // Navigate to register page
});
</script>

<!-- Form Validation Script -->
<script>
(function () {
'use strict';
var forms = document.querySelectorAll('.needs-validation');
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
})();
</script>
</body>
</html>
Loading