Skip to content

Commit

Permalink
Added: Time Capsule Center(VanillaJS) (#749)
Browse files Browse the repository at this point in the history
* Added: Time Capsule Center(VanillaJS)

* Review changes
  • Loading branch information
kosuri-indu authored Aug 8, 2024
1 parent 0efddae commit f6c1fde
Show file tree
Hide file tree
Showing 6 changed files with 516 additions and 1 deletion.
68 changes: 68 additions & 0 deletions Vanilla-JS-Projects/Intermediate/Time-Capsule-Center/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<h1 align='center'><b>💥 Time Capsule Center 💥</b></h1>

<!-- -------------------------------------------------------------------------------------------------------------- -->

<h3 align='center'>Tech Stack Used 🎮</h3>
<!-- enlist all the technologies used to create this project from them (Remove comment using 'ctrl+z' or 'command+z') -->

<div align='center'>

![HTML5](https://img.shields.io/badge/html5-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white)
![CSS3](https://img.shields.io/badge/css3-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white)
<!-- ![Bootstrap](https://img.shields.io/badge/bootstrap-%238511FA.svg?style=for-the-badge&logo=bootstrap&logoColor=white) -->
![JavaScript](https://img.shields.io/badge/javascript-%23323330.svg?style=for-the-badge&logo=javascript&logoColor=%23F7DF1E)
<!-- ![jQuery](https://img.shields.io/badge/jquery-%230769AD.svg?style=for-the-badge&logo=jquery&logoColor=white) -->
<!-- ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) -->
<!-- ![Redux](https://img.shields.io/badge/redux-%23593d88.svg?style=for-the-badge&logo=redux&logoColor=white) -->
<!-- ![TailwindCSS](https://img.shields.io/badge/tailwindcss-%2338B2AC.svg?style=for-the-badge&logo=tailwind-css&logoColor=white) -->
<!-- ![Web3.js](https://img.shields.io/badge/web3.js-F16822?style=for-the-badge&logo=web3.js&logoColor=white) -->
<!-- ![Express.js](https://img.shields.io/badge/express.js-%23404d59.svg?style=for-the-badge&logo=express&logoColor=%2361DAFB) -->
<!-- ![Angular.js](https://img.shields.io/badge/angular.js-%23E23237.svg?style=for-the-badge&logo=angularjs&logoColor=white) -->
<!-- ![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white) -->
<!-- ![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white) -->
<!-- ![Vue.js](https://img.shields.io/badge/vuejs-%2335495e.svg?style=for-the-badge&logo=vuedotjs&logoColor=%234FC08D) -->
<!-- ![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white) -->
</div>

![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847)

<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: Description 📃

- A web application to help you store memories in terms of time capsules for future.

<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: How to run it? 🕹️

<!-- add the steps how to run the project -->
- Fork this repository.
- Clone the forked repository.
- Open index.html in your web browser to start your culinary exploration.

<!-- -------------------------------------------------------------------------------------------------------------- -->

## :zap: Screenshots 📸
<!-- add the screenshot of the project (Mandatory) -->

![Screenshot 2024-08-07 011353](https://github.com/user-attachments/assets/800ed567-67fa-476f-891c-34331e916477)
![Screenshot 2024-08-07 011805](https://github.com/user-attachments/assets/939c3a3c-0046-41f4-b74f-3e5ec4c564fc)
![Screenshot 2024-08-07 011851](https://github.com/user-attachments/assets/8bdb336d-948c-4547-a3da-e07f9dfb9abb)


![Line](https://github.com/Avdhesh-Varshney/WebMasterLog/assets/114330097/4b78510f-a941-45f8-a9d5-80ed0705e847)


<!-- -------------------------------------------------------------------------------------------------------------- -->

<h4 align='center'>Developed By <b><i>Kosuri Indu</i></b> </h4>
<p align='center'>
<a href='https://github.com/kosuri-indu'>
<img src='https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white' />
</a>
</p>

<h4 align='center'>Happy Coding 🧑‍💻</h4>

<h3 align="center">Show some &nbsp;❤️&nbsp; by &nbsp;🌟&nbsp; this repository!</h3>
77 changes: 77 additions & 0 deletions Vanilla-JS-Projects/Intermediate/Time-Capsule-Center/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Time Capsule Center</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body>
<div class="container">
<header>
<h1>Time Capsule Center</h1>
<nav>
<ul>
<li><a href="#addCapsule" class="nav-link">Add Time Capsule</a></li>
<li><a href="#statistics" class="nav-link">Statistics</a></li>
<li><a href="#capsuleStorage" class="nav-link">Capsule Storage</a></li>
</ul>
</nav>
</header>
<!-- Form to add a time capsule -->
<section id="addCapsule" class="page">
<h2>Add Time Capsule</h2>
<form id="timeCapsuleForm">
<label for="capsuleName">Capsule Name:</label>
<input type="text" id="capsuleName" name="capsuleName" required>
<label for="openDate">Open Date:</label>
<input type="date" id="openDate" name="openDate" required>
<label for="tags">Tags:</label>
<input type="text" id="tags" name="tags" placeholder="Enter tags separated by commas">
<label for="message">Message:</label>
<textarea id="message" name="message" required></textarea>
<label for="image">Image (optional):</label>
<input type="file" id="image" name="image" accept="image/*">
<label for="video">Video (optional):</label>
<input type="file" id="video" name="video" accept="video/*">
<button type="submit">Create Capsule</button>
</form>
</section>
<section id="statistics" class="page">
<h2>Statistics</h2>
<div id="overallStatistics" class="statistics-item">
<h3>Overall Statistics</h3>
<p id="totalCapsules">Total Capsules: 0</p>
<p id="totalMessages">Total Messages: 0</p>
<p id="totalImages">Total Images: 0</p>
<p id="totalVideos">Total Videos: 0</p>
</div>
<div id="recentActivity" class="statistics-item">
<h3>Recent Activity</h3>
<ul id="recentCapsules"></ul>
</div>
<div id="upcomingCapsules" class="statistics-item">
<h3>Upcoming Capsules</h3>
<ul id="upcomingCapsuleList"></ul>
</div>
</section>
<section id="capsuleStorage" class="page">
<h2>Capsule Storage</h2>
<input type="text" id="searchBar" placeholder="Search capsules by name or tags">
<div id="capsuleList"></div>
</section>
</div>
<div id="capsuleModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2 id="modalCapsuleName"></h2>
<p id="modalCapsuleMessage"></p>
<img id="modalCapsuleImage" src="" alt="Capsule Image" style="display:none;">
<video id="modalCapsuleVideo" controls style="display:none;"></video>
</div>
</div>
<div id="notification" class="notification"></div>
<script src="script.js"></script>
</body>
</html>
Binary file not shown.
214 changes: 214 additions & 0 deletions Vanilla-JS-Projects/Intermediate/Time-Capsule-Center/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('timeCapsuleForm');
const capsuleList = document.getElementById('capsuleList');
const searchBar = document.getElementById('searchBar');
const notification = document.getElementById('notification');
const statisticsContainer = document.getElementById('statisticsContainer');
let capsules = [];

form.addEventListener('submit', (e) => {
e.preventDefault();

const capsuleName = document.getElementById('capsuleName').value;
const openDate = new Date(document.getElementById('openDate').value);
const tags = document.getElementById('tags').value.split(',').map(tag => tag.trim());
const message = document.getElementById('message').value;
const image = document.getElementById('image').files[0];
const video = document.getElementById('video').files[0];

const capsule = {
name: capsuleName,
openDate: openDate,
tags: tags,
message: message,
image: image ? URL.createObjectURL(image) : null,
video: video ? URL.createObjectURL(video) : null,
};

capsules.push(capsule);
updateDashboard();
updateStatistics();
showNotification('New capsule added successfully!');
form.reset();
});

searchBar.addEventListener('input', updateDashboard);

function updateDashboard() {
capsuleList.innerHTML = '';
const searchQuery = searchBar.value.toLowerCase();
const filteredCapsules = capsules.filter(capsule =>
capsule.name.toLowerCase().includes(searchQuery) ||
capsule.tags.some(tag => tag.toLowerCase().includes(searchQuery))
);

filteredCapsules.forEach((capsule, index) => {
const capsuleItem = document.createElement('div');
capsuleItem.classList.add('capsule-item');

const nameSpan = document.createElement('span');
nameSpan.textContent = capsule.name;
capsuleItem.appendChild(nameSpan);

const dateSpan = document.createElement('span');
dateSpan.textContent = capsule.openDate.toDateString();
capsuleItem.appendChild(dateSpan);

const tagsSpan = document.createElement('span');
tagsSpan.textContent = capsule.tags.join(', ');
capsuleItem.appendChild(tagsSpan);

const countdownSpan = document.createElement('span');
countdownSpan.id = `countdown${index}`;
capsuleItem.appendChild(countdownSpan);

const editButton = document.createElement('button');
editButton.classList.add('edit-btn');
editButton.textContent = 'Delete';
editButton.addEventListener('click', () => editCapsule(index));
capsuleItem.appendChild(editButton);

capsuleItem.addEventListener('click', (e) => {
if (e.target.tagName !== 'BUTTON') {
showCapsuleDetails(capsule);
}
});

capsuleList.appendChild(capsuleItem);
updateCountdown(capsule, index);
});
}

function updateCountdown(capsule, index) {
const countdownElement = document.getElementById(`countdown${index}`);
const interval = setInterval(() => {
const now = new Date();
const distance = capsule.openDate - now;

if (distance < 0) {
clearInterval(interval);
countdownElement.textContent = 'Available to open';
return;
}

const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);

countdownElement.textContent = `${days}d ${hours}h ${minutes}m ${seconds}s`;
}, 1000);
}

function showCapsuleDetails(capsule) {
const modal = document.getElementById('capsuleModal');
const modalCapsuleName = document.getElementById('modalCapsuleName');
const modalCapsuleMessage = document.getElementById('modalCapsuleMessage');
const modalCapsuleImage = document.getElementById('modalCapsuleImage');
const modalCapsuleVideo = document.getElementById('modalCapsuleVideo');
const closeBtn = document.querySelector('.close');

if (new Date() < capsule.openDate) {
alert('This capsule cannot be opened yet.');
return;
}

modalCapsuleName.textContent = capsule.name;
modalCapsuleMessage.textContent = capsule.message;

if (capsule.image) {
modalCapsuleImage.style.display = 'block';
} else {
modalCapsuleImage.style.display = 'none';
}

if (capsule.video) {
modalCapsuleVideo.style.display = 'block';
} else {
modalCapsuleVideo.style.display = 'none';
}

modal.style.display = 'block';

closeBtn.onclick = function () {
modal.style.display = 'none';
};

window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = 'none';
}
};
}

function editCapsule(index) {
const capsule = capsules[index];
document.getElementById('capsuleName').value = capsule.name;
document.getElementById('openDate').value = capsule.openDate.toISOString().split('T')[0];
document.getElementById('tags').value = capsule.tags.join(', ');
document.getElementById('message').value = capsule.message;
capsules.splice(index, 1);
updateDashboard();
updateStatistics();
}

function showNotification(message) {
notification.textContent = message;
notification.style.display = 'block';
setTimeout(() => {
notification.style.display = 'none';
}, 3000);
}

function updateStatistics() {
const totalCapsules = capsules.length;
const tagCounts = capsules.reduce((acc, capsule) => {
capsule.tags.forEach(tag => {
acc[tag] = (acc[tag] || 0) + 1;
});
return acc;
}, {});

const mostCommonTags = Object.entries(tagCounts)
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.map(([tag, count]) => `${tag} (${count})`)
.join(', ');

const dateCounts = capsules.reduce((acc, capsule) => {
const date = capsule.openDate.toDateString();
acc[date] = (acc[date] || 0) + 1;
return acc;
}, {});

const distribution = Object.entries(dateCounts)
.map(([date, count]) => `${date}: ${count}`)
.join('<br>');

statisticsContainer.innerHTML = '';
const statsTitle = document.createElement('h3');
statsTitle.textContent = 'Capsule Statistics';
statisticsContainer.appendChild(statsTitle);

const totalCapsulesP = document.createElement('p');
totalCapsulesP.textContent = `Total Capsules: ${totalCapsules}`;
statisticsContainer.appendChild(totalCapsulesP);

const mostCommonTagsP = document.createElement('p');
mostCommonTagsP.textContent = `Most Common Tags: ${mostCommonTags}`;
statisticsContainer.appendChild(mostCommonTagsP);

const distributionP = document.createElement('p');
distributionP.innerHTML = `Distribution by Opening Date:<br>${distribution}`;
statisticsContainer.appendChild(distributionP);
}

document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', function () {
document.querySelectorAll('.page').forEach(page => page.classList.remove('active'));
document.querySelector(this.getAttribute('href')).classList.add('active');
});
});

document.getElementById('addCapsule').classList.add('active');
});
Loading

0 comments on commit f6c1fde

Please sign in to comment.