diff --git a/appointment.png b/appointment.png new file mode 100644 index 0000000..90622c2 Binary files /dev/null and b/appointment.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..36bbb2e --- /dev/null +++ b/index.html @@ -0,0 +1,93 @@ + + + + + + + + + Appointment Management App + + + + + + + +
+ +

Welcome to the Appointment Management System

+
+
+ + + + +
+
+ + +
Dentist
+
12/04/2024
+
12:00pm CST
+
+ 1234 S Drexel Ave Chicago,IL 60637 +
+
+
+ + +
Therapy
+
12/15/2024
+
1:00pm CST
+
+ 432 S Dearborn Ave Chicago,IL 60627 +
+
+
+ + +
+

Enter an appointment

+
+ + + + + + + + + +
+
+ + +
+

+ Your next appointment is in 5 days

+ +
+ +
+ + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..c85ac88 --- /dev/null +++ b/script.js @@ -0,0 +1,200 @@ +'use strict'; +//document.addEventListener('DOMContentLoaded', function () { +const appointment1 = { + // id: 1, + type: 'Dentist', + date: new Date(), + time: '2:00:00 PM', + location: '432 S Dearborn Ave Chicago,IL 60627', +}; + +const appointment2 = { + //id: 2, + type: 'Gynaecologist', + date: new Date(), + time: '1:00:00 PM', + location: '1234 S Drexel Ave Chicago,IL 60637', +}; + +const appointments = [appointment1, appointment2]; +// const appointments = []; + +//Select DOM elements +const apptContainer = document.querySelector('.appointments'); +const rows = document.querySelectorAll('.appointments-row'); +const deleteBtns = document.querySelectorAll('.delete'); +const edit = document.querySelectorAll('.appointments-btn-edit'); +const apptSubmit = document.querySelector('.form-btn'); +const apptType = document.querySelector('.form-input-type'); +const apptDate = document.querySelector('.form-input-date'); +const apptTime = document.querySelector('.form-input-time'); +const apptLocation = document.querySelector('.form-input-location'); +const dayCount = document.querySelector('.days'); +const sortBtn = document.querySelector('.sort-btn'); +const datePicker = document.querySelector('.form-input-date'); +const popup = document.querySelector('.modal'); +const closeModal = document.querySelector('.close-modal'); +const overlayBG = document.querySelector('.overlay'); +const deleteMsg = document.querySelector('.deleteMsg'); + +//Display Appointments from objects +const displayAppts = function (appt, sort = false) { + //emtpy out the comtainer + apptContainer.innerHTML = ''; + + appt.forEach(function (el, i) { + const html = `
+ + +
${el.type}
+
${el.date.toLocaleDateString()}
+
${el.time}
+
+ ${el.location} +
`; + //input html into container + apptContainer.insertAdjacentHTML('afterbegin', html); + }); +}; + + +const today = new Date(); +// console.log(today.toISOString()); +// console.log(today.toISOString().slice(0,16)); +//Setting the date pickerminimum date +datePicker.setAttribute('min', today.toISOString().slice(0, 16)); +// datePicker.setAttribute("max", "2024-03-31T00:00"); + +const calcDaysPassed = (date1, date2) => + Math.round((date2 - date1) / (1000 * 60 * 60 * 24)); + +const setTimer = function () { + let days = []; + + appointments.forEach((appt, i, arr) => + days.push(calcDaysPassed(today, appt.date)) + ); + console.log(days); + let closest = days[0]; + days.forEach((day, i, arr) => { + if (day < closest) { + closest = day; + } + }); + + //IF THERE ARE APPOINTMENTS THEN SET the day count IF NOT THEN PUT 0 + if (appointments.length > 0) { + dayCount.textContent = closest; + } else { + dayCount.textContent = 0; + } + console.log(dayCount.textContent); +}; + +//Update UI +const updateUI = function (appts) { + displayAppts(appts); + setTimer(); + // console.log(appointments); +}; + +updateUI(appointments); +//Function to add an new appointment +const addAppt = function () { + ///Formating the date + const date = new Date(apptDate.value); + const newAppt = { + // id: appointments.lastIndexOf + type: apptType.value, + //.toLocalString() - takes the date and time and sets to string + date: date, + time: date.toLocaleTimeString(), + location: apptLocation.value, + // deleted: false, + }; + appointments.push(newAppt); + updateUI(appointments); + //console.log(apptContainer); +}; + +const deleteAppt = function (id) { + //console.log('Deleted index:', id); + // appointments = appointments.filter(appt => { + // return appt.id !== id; + // }); + appointments.forEach((appt, i, arr) => { + if (i + 1 === id) { + // console.log('test cond', i); + appointments.splice(i, 1); + // console.log(id); + // console.log(i); + deleteMsg.innerHTML = `

You successfully deleted your ${appt.type} appointment for ${appt.date.toDateString()} at ${appt.time}

`; + } + }); + //console.log(appointments); + updateUI(appointments); + //console.log(apptContainer); +}; + +apptSubmit.addEventListener('click', function (e) { + //alert('List will be unsorted'); + e.preventDefault(); + //console.log('button clicked', e.target.closest('.form-btn')); + addAppt(); + // console.log(appointments); + apptDate.value = ''; + apptLocation.value = ''; + apptType.value = ''; + updateUI(appointments); +}); + +// +// console.log(appointments); +// Because we can not add an event listener to all the delete button elements +//We add the event listen to the general container and look to see if what is clicked has the name of the class we want +apptContainer.addEventListener('click', function (e) { + //if the class list of the lciked element has delete + if (e.target.classList.contains('delete')) { + //print our for error check! and getting teh id attribute associated with the click + console.log( + 'this id was clicked and deleted', + e.target.getAttribute('data-id') + ); + popup.classList.remove('hidden'); + overlayBG.classList.remove('hidden'); + } + + + ///If modal window is closed + closeModal.addEventListener('click', function (e) { + popup.classList.add('hidden'); + overlayBG.classList.add('hidden'); +}) + + //get the id + let id = parseInt(e.target.getAttribute('data-id')); + //put that id in the deleteAppt tag + deleteAppt(id); +}); +let sortedAppts = []; +// let sorted = false; +const sortAppts = function () { + // sortedAppts = appointments.slice().sort((a, b) => b.date - a.date); + appointments.sort((a, b) => b.date - a.date); + updateUI(appointments); + displayAppts(appointments); +}; + +sortBtn.addEventListener('click', function (e) { + e.preventDefault(); + sortAppts(); +}); + + +// appointments.forEach((appt, i, arr) => { +// if (calcDaysPassed(today, appt.date) <= 0) { +// deleteAppt(i); +// updateUI(appointments); +// console.log('thats an old appt'); +// } +// }); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..d76102b --- /dev/null +++ b/style.css @@ -0,0 +1,273 @@ +/* Removes margins from whole page */ +* { + margin: 0; + padding: 0; + box-sizing: inherit; +} + +html { + font-size: 75%; + box-sizing: border-box; +} + +body { + font-family: 'Poppins', sans-serif; + color: #444; + background-color: #7ea07cca; + height: 100vh; + padding: 2rem; +} + +img { + overflow-clip-margin: content-box; + overflow: clip; +} + +.logo { + height: 6rem; +} + +.welcome { + font-size: 3rem; + font-weight: 500; + text-align: center; + color: #333; +} + +/* MAIN */ +.app { + position: relative; + max-width: 110rem; + margin: 4rem auto; + display: grid; + /* a grid of two columns*/ + grid-template-columns: 5fr 3fr; + grid-template-rows: auto repeat(3, 15rem) auto; + gap: 2em; + transition: all 1s; +} + +.summary { + grid-column: 1 / span 2; + display: flex; + align-items: flex-start; + justify-content: space-between; + /* margin-bottom: 2rem; */ +} +.summaryMsg { + font-size: 1.2rem; + /* font-weight: 500; */ + margin-bottom: -0.2rem; + color: #333; +} + +/*Appointments*/ + +.appointment-timer { + font-weight: 800; + font-size: 1.2rem; + color: #333; +} +.appointments { + grid-row: 2 / span 3; + background-color: #fff; + border-radius: 1rem; + overflow: scroll; +} + +.appointments-row { + padding: 2.25rem 4rem; + display: flex; + align-items: center; + border-bottom: 1px solid #eee; +} +.appointments-type { + font-size: 1.1rem; + margin-left: .5em; + text-transform: uppercase; + font-weight: 500; + color: #fff; + padding: 0.1rem 1rem; + border-radius: 10rem; + box-shadow: 0.01em 0.2em 0.1em #062481; + /* margin-right: 2rem; */ + background-color: #f95d95; +} + +.appointments-date, +.appointments-time, +.appointments-location { + font-size: 1.1rem; + text-transform: uppercase; + padding: 0.1rem 1rem; + font-weight: 500; + color: #666; +} + +.appointments-btn-cancel, +.appointments-btn-edit { + padding: 0.1rem 1rem; + margin-right: 2rem; + border: none; + border-radius: 0.7rem; + cursor: pointer; + transition: all 0.3s; +} + +/*FORM */ +.appointment-form { + grid-row: 2; + border-radius: 1rem; + padding: 3rem 2rem; + color: #333; + background-color: #f95d95; + border: dashed .25rem #fff; +} + +.appointment-form-header { + margin-bottom: 1.5rem; + font-size: 1.5rem; + font-weight: 500; + color: #ffffff; +} + +.form { + display: grid; + grid-template-columns: 4fr 4fr 4fr 1fr; + grid-template-rows: auto auto; + gap: 0.4rem 1rem; +} + +.form-input { + width: 100%; + border: none; + background-color: rgba(255, 255, 255, 0.4); + font-family: inherit; + font-size: 0.95rem; + text-align: center; + color: #333; + padding: 0.3rem 1rem; + border-radius: 0.7rem; + transition: all 0.3s; +} + +.form-label { + font-size: 0.95rem; + text-align: center; +} + +.form-input:focus { + outline: none; + background-color: rgba(255, 255, 255, 0.697); +} + +.form-btn { + border: none; + border-radius: 0.7rem; + font-size: 1.8rem; + background-color: #fff; + cursor: pointer; + transition: all 0.3s; +} + +.form-btn:focus { + outline: none; + background-color: rgba(255, 255, 255, 0.8); +} + +.appointment-timer { + font-weight: 300; + font-size: 1.7rem; + color: #333; +} + +.days { + color: #ed0e2f; + font-weight: 400; + text-decoration: underline; +} + +/* MODAL WINDOW */ +.modal { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 60rem; + background-color: #f3f3f3; + padding: 5rem 6rem; + box-shadow: 0 4rem 6rem rgba(0, 0, 0, 0.3); + z-index: 1000; + transition: all 0.5s; +} + +.hidden { + visibility: hidden; + opacity: 0; +} + +.timeWrapper { + display: flex; + /* align-items: center; */ + justify-content: space-between; +} + +.sort-btn { + align-self: flex-end; + flex: 0 1 8rem; + padding: 0.6rem 1rem; + border-radius: .5rem; + font-size: 1.2rem; + font-weight: 800; + background-color: #fff; + color: #f95d95; +} + +.modal { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 70%; + + background-color: white; + padding: 6rem; + border-radius: 5px; + box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3); + z-index: 10; +} + +.show-modal { + font-size: 2rem; + font-weight: 600; + padding: 1.75rem 3.5rem; + margin: 5rem 2rem; + border: none; + background-color: #fff; + color: #444; + border-radius: 10rem; + cursor: pointer; +} + +.close-modal { + position: absolute; + top: 1.2rem; + right: 2rem; + font-size: 5rem; + color: #333; + cursor: pointer; + border: none; + background: none; +} +/* settings to turn page out of focus */ +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + /* background-color: rgba(255, 255, 255, 0.6); */ + background-color: #7ea07c79; + backdrop-filter: blur(3px); + z-index: 5; +}