Skip to content

Commit

Permalink
Merge pull request #96 from jen67/manage
Browse files Browse the repository at this point in the history
Completed the age calculator app challenge
  • Loading branch information
jen67 authored Jan 12, 2024
2 parents ee07dd5 + 32e2fa8 commit ac77b4d
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 23 deletions.
18 changes: 9 additions & 9 deletions age-calculator-app-main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<link rel="icon" type="image/png" sizes="32x32" href="./assets/images/favicon-32x32.png">
<link rel="stylesheet" href="styles.css">
<script src="./script.js" defer ></script>

<title>Frontend Mentor | Age calculator app</title>

Expand All @@ -21,31 +22,31 @@
<div>
<label for="day">Day</label>
<input type="text" id="day" name="day" maxlength="2" placeholder="DD" required>
<p class="hidden-text"></p>
<p class="error-text-day error-texts"></p>
</div>
<div>
<label for="month">Month</label>
<input type="text" id="month" name="month" maxlength="2" placeholder="MM" required>
<p class="hidden-text"></p>
<p class="error-text-month error-texts"></p>
</div>
<div>
<label for="year">Year</label>
<input type="text" id="year" name="year" maxlength="4" placeholder="YYYY" required>
<p class="hidden-text"></p>
<p class="error-text-year error-texts"></p>
</div>
</form>
<div>
<div class="hr-line">
<hr>
<div><img src="./assets/images/icon-arrow.svg" alt="arrow-img"></div>
<div class="btn"><img src="./assets/images/icon-arrow.svg" alt="arrow-img"></div>
</div>
<div class="years">
<h1><span class="lines"> --</span> Years </h1>
<h1><span class="lines line1"> --</span> years </h1>
</div>
<div class="months">
<h2><span class="lines"> --</span> months</h2>
<h2><span class="lines line2"> --</span> months</h2>
</div>
<div class="days">
<div class="days line3">
<h3><span class="lines"> --</span> days</h3>
</div>
</div>
Expand All @@ -54,9 +55,8 @@ <h3><span class="lines"> --</span> days</h3>
<footer>
<div class="attribution">
Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
Coded by <a href="#">Your Name Here</a>.
Coded by <a href="#">Gift Amachree</a>.
</div>
</footer>
</body>

</html>
135 changes: 135 additions & 0 deletions age-calculator-app-main/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(function () {
"use strict";

const button = document.querySelector(".btn");
const birthDay = document.querySelector("#day");
const birthMonth = document.querySelector("#month");
const birthYear = document.querySelector("#year");
const years = document.querySelector(".years span");
const months = document.querySelector(".months span");
const days = document.querySelector(".days span");
const erroTextYear = document.querySelector(".error-text-year");
const erroTextMonth = document.querySelector(".error-text-month");
const erroTextDay = document.querySelector(".error-text-day");
const labels = document.querySelectorAll("label[for]");
const errorBorders = document.querySelectorAll("input");

function animateValue(element, start, end, duration) {
let current = start;
let range = end - start;
let increment = end > start ? 1 : -1;
let stepTime = Math.abs(Math.floor(duration / range));
let timer = setInterval(function () {
current += increment;
element.textContent = ` ${current}`;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}

function checkAge() {
const day = parseInt(birthDay.value, 10);
const month = parseInt(birthMonth.value, 10);
const year = parseInt(birthYear.value, 10);

const currentDate = new Date();
const birthDate = new Date(year, month - 1, day);

// Reset error messages and styles
function resetError() {
erroTextDay.textContent = "";
erroTextMonth.textContent = "";
erroTextYear.textContent = "";
labels.forEach((label) => {
label.style.color = "var(--Smokey-grey)";
});
errorBorders.forEach((error) => {
error.style.borderColor = "var(--Light-grey)";
});
}

resetError();

let hasError = false;

function update() {
labels.forEach((label) => {
label.style.color = "var(--Light-red)";
});
years.textContent = "--";
months.textContent = "--";
days.textContent = "--";
}

// Check if the entered date is valid
if (isNaN(day) || day < 1 || day > 31) {
erroTextDay.textContent = "Invalid day";
document.querySelector("label[for='day']").style.color =
"var(--Light-red)";
birthDay.style.borderColor = "var(--Light-red)";
birthMonth.style.borderColor = "var(--Light-red)";
birthYear.style.borderColor = "var(--Light-red)";
hasError = true;
}

if (isNaN(month) || month < 1 || month > 12) {
erroTextMonth.textContent = "Invalid month.";
document.querySelector("label[for='month']").style.color =
"var(--Light-red)";
birthMonth.style.borderColor = "var(--Light-red)";
birthDay.style.borderColor = "var(--Light-red)";
birthYear.style.borderColor = "var(--Light-red)";
hasError = true;
}

if (isNaN(year) || year < 1 || year > currentDate.getFullYear()) {
erroTextYear.textContent = "Invalid year.";
document.querySelector("label[for='year']").style.color =
"var(--Light-red)";
birthYear.style.borderColor = "var(--Light-red)";
birthDay.style.borderColor = "var(--Light-red)";
birthMonth.style.borderColor = "var(--Light-red)";
hasError = true;
}

if (hasError) {
update();
return;
}

// Calculate the age
if (birthDate <= currentDate) {
let ageInYears = currentDate.getFullYear() - birthDate.getFullYear();
let ageInMonths = currentDate.getMonth() - birthDate.getMonth();
let ageInDays = currentDate.getDate() - birthDate.getDate();

if (ageInDays < 0) {
const lastMonth = new Date(
currentDate.getFullYear(),
currentDate.getMonth() - 1,
birthDate.getDate()
);
const daysInLastMonth = new Date(
currentDate.getFullYear(),
currentDate.getMonth(),
0
).getDate();
ageInDays =
daysInLastMonth - lastMonth.getDate() + currentDate.getDate();
ageInMonths--;
}

if (ageInMonths < 0) {
ageInMonths = 12 + ageInMonths;
ageInYears--;
}

// Display the calculated age
animateValue(years, 0, ageInYears, 1000);
animateValue(months, 0, ageInMonths, 1000);
animateValue(days, 0, ageInDays, 1000);
}
}
button.addEventListener("click", checkAge);
})();
137 changes: 123 additions & 14 deletions age-calculator-app-main/styles.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;700;800&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,700;1,400;1,800&display=swap");

:root {
/* primary */
Expand Down Expand Up @@ -32,21 +32,22 @@ body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.container {
padding: 1rem 2rem;
width: 400px;
margin: 4rem auto;
padding: 2rem 1rem;
width: 90vw;
background-color: var(--White);
border-radius: 1.2rem 1.2rem 8rem 1.2rem;
}

form {
display: flex;
flex-direction: row;
align-items: center;
gap: 1rem;
width: 70%;
padding-bottom: 3rem;
}

form div {
Expand All @@ -56,9 +57,9 @@ form div {
}

form label {
font-weight: 400;
text-transform: uppercase;
font-size: 0.5rem;
font-size: 0.9rem;
letter-spacing: 0.2rem;
color: var(--Smokey-grey);
display: flex;
flex-direction: column;
Expand All @@ -68,43 +69,151 @@ form label {

form input {
width: 100%;
padding: 0.3rem;
padding: 1rem;
font-size: 1.3rem;
border: 1px solid var(--Light-grey);
border-radius: 5px;
color: var(--Smokey-grey);
color: var(--off-black);
font-weight: 700;
font-family: inherit;
}

form input:focus {
outline: none;
border: 1px solid var(--Purple);
}

.hr-line {
position: relative;
padding-top: 1rem;
}

.hr-line hr {
border: none;
border: 1px solid var(--Off-white);
}

.hr-line div {
display: flex;
align-items: center;
background-color: var(--Purple);
border-radius: 50%;
height: 50px;
width: 50px;
padding: 0.5rem;
padding: 0.8rem;
position: absolute;
top: -0.5rem;
left: 90%;
top: -1.5rem;
left: 40%;
z-index: 1;
transition: all 0.3s ease-in-out;
}

.hr-line div:hover {
background-color: var(--off-black);
}

h1,
h2,
h3 {
font-size: 1.8rem;
font-size: 3rem;
font-weight: 800;
color: var(--off-black);
line-height: 1.1;
}

.error-texts {
color: var(--Light-red);
font-size: 0.6rem;
font-weight: 400;
}

.error-border{
border-color: var(--Light-red);
}

.years {
padding-top: 3rem;
}

span.lines {
color: var(--Purple);
}

footer {
width: 290px;
text-align: center;
margin: 1rem auto;
}

.attribution {
font-size: 0.8rem;
color: var(--Smokey-grey);
}

.attribution a {
text-decoration: none;
color: var(--Smokey-grey);
font-style: oblique;
border-radius: 20px;
border-bottom: 1px solid var(--Smokey-grey);
}

.attribution a:hover {
color: var(--Purple);
border-bottom: 1px solid var(--Purple);
font-weight: 800;
}

@keyframes fadeIn{
from{
opacity: 0;
}
to{
opacity: 1;
}
}

fadeIn{
animation: fadeIn 2s ease-in-out;
}


@media screen and (min-width: 768px) {
body {
justify-content: center;
}

.container {
width: 500px;
margin: 0;
padding:2rem;
}

form {
width: 70%;
padding-bottom: 1rem;
}

form input{
width: 110px;
padding: 0.5rem;
}

.hr-line div {
left: 90%;
}

h1,
h2,
h3 {
font-size: 4rem;

}

.years{
padding-top: 1rem;
}

footer{
padding-top:4rem;
}
}

2 comments on commit ac77b4d

@vercel
Copy link

@vercel vercel bot commented on ac77b4d Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on ac77b4d Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

dropdown-nav – ./intro-section-with-dropdown-navigation-main

dropdown-nav-three.vercel.app
dropdown-nav-gift-amachrees-projects.vercel.app
dropdown-nav-git-main-gift-amachrees-projects.vercel.app

Please sign in to comment.