Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found

All solutions

  • Submitted


    To see the full app visit this link: https://entertainment.rugh.us/ The link I provided for this submission is frontend only. For some reason the bookmark flag images are not working, but on the full stack app they are working fine.

    For this project I created a full stack app. For the backend I used Python, Flask and MySQL. This was my first time using Python and Flask and so I learned a whole bunch about the language and framework. It was also my first time to use MySQL outside of a classroom environment and I was able to reinforce concepts previously learned.

  • Submitted

    Connect Four

    • HTML
    • CSS
    • JS

    0


    What I learned For me, this project was a marathon. I find that projects drag out for me due to my inability to accurately plan before starting to code. Often I hit my MVP and I am happy with it, then I go back to add new features and the MVP begins to unravel. Soon I am left with a tangled mess that would no longer qualify as an MVP. Thankfully git allows an easy way to step back and start again from any point.

    For this project I forced myself to utilize useContext in React. Previously I had been "prop drilling" and the code was becoming massive and unreadable. I am not entirely sure that I utilized useContext with best practice (my context files are a bit out of control) but I found it far easier to utilize useContext than to prop drill.

    A second thing I learned was how to use pointer-events with CSS. I an into an issue where the game board and game piece would at some point display in the wrong order. This was because I was using a higher z-index on the game piece so that it could be clicked and used. But with the higher z-index, the piece would settle on top of the game board and not give the appearance as if it were behind the game board. Switching the z-index of the piece and board would give the correct appearance but not allow any additional pieces to be clicked. The solution was to keep the board above the pieces with z-index, and also use pointer-events: none on the game board. This allows for the next layer to be clicked and the z-index order to remain intact and consistent.

    Continued development I had to compromise with this project. Animation works, but only while playing 2 player. Vs the CPU I have turned the animation off. This is the situation I was referring to above. Continued development looks like figuring out the best way to add animation to the CPU logic without having to start completely over.

  • Submitted


    This project was probably the most challenging one to date on this site. I grew a lot in my understanding of javascript and was able to practice with some tools. Mainly localstorage, findIndexOf etc. I found myself having to refactor the code several times. The look was correct, but the logic forced me to change the look, then the logic was incorrect after adjusting the look. My mistake was making a gameplan solely based on the mobile design. Instead I need to make a plan with the entire design in mind so I can account for those changes that occur at larger widths. I did not complete all of the active state pieces for this reason.

  • Submitted

    galleria

    • HTML
    • CSS
    • JS

    0

  • Submitted

    Clock

    • HTML
    • CSS
    • JS
    • API

    0

  • Submitted

    Space

    • HTML
    • CSS
    • JS

    0


    The first thing I learned was how to solve the white space issue when using height: 100vh. This has been an issue for me with most projects I have done.

    Here is the issue that height: 100vh creates:

    The fix is to use display flex, flex-direction column and height 100vh in the parent div. Then in the last child div use flex grow:1 and height auto.

    Here is the code:

    
    <div className="App flex flex-col h-screen">
    <div id='mainWrapper' className='flex justify-center h-auto grow bg-[url("/src/assets/home/background-home-mobile.jpg")] bg-cover pt-6 pb-12 bg-no-repeat mix-blend-screen'>
    
    

    ... well, fast forward a few days... and the above was not the solution. It helped, but I spent a few hours more customizing a javascript function to elminate the white space on all screen sizes. I think I have the solution now.

    useEffect(()=>{
    // change the height
    let mainWrapper = document.getElementById("mainWrapper"); 
    let appOriginalHeight = document.getElementById('mainApp').clientHeight
    let mainWrapperHeight = mainWrapper.clientHeight
        
    if (appOriginalHeight < mainWrapperHeight) {
    let difference = mainWrapperHeight - appOriginalHeight
    document.getElementById('mainApp').style.height = appOriginalHeight + difference + 'px'
    } else if (appOriginalHeight >= mainWrapperHeight) {
    console.log('main O is less')
    }
    },[])
    

    Basically the code takes note of the original height of the app div (content) then as clicks are made compares the app div height to the height of the main content div. Next it figures out the difference in height between the 2 divs. If the main content div is larger (in height) than the original height of the app div then the code adds the difference in px to the main app div. I did not figure out how to revert it. As it stands if a click is made on the destination links then the app height is expanded from then on out for any new link clicked. In the best world I would have it revert back to the original height that fits the content appropriately.

  • Submitted

    Calculate This

    • HTML
    • CSS
    • JS

    0


    So much refactoring. I am just glad this one is done.

  • Submitted

    Countdown Timer

    • HTML
    • CSS
    • JS

    0


    This project was a nice challenge. It allowed me to continue to get used to passing props in React, troubleshoot some tricky designs and practice some logic javascript. My code was quite complicated in several places at first. At some point I realized my logic was creating bugs and from there was able to make a much more practical countdown function.

    // add 14 days to today on load
    function addDays(date, days) {
    let result = new Date(date);
    result.setDate(result.getDate() + days);
    let theSeconds = result.getSeconds()
    let theMinutes = result.getMinutes()
    let theHours = result.getHours()
    let theDays = days
    
    let theSecondsCount = setInterval(function() {
    theSeconds = theSeconds -1
    if( theSeconds < 0 ) {
    console.log('single')
    theSeconds = 59
    theMinutes--
    document.getElementById('minText').classList.add('animate__flipInX')
    if ( theMinutes < 0 ) {
    console.log('double')
    theMinutes = 59
    theHours--
    document.getElementById('hourText').classList.add('animate__flipInX')
    if ( theHours < 0) {
    console.log('triple')
    theHours = 23
    theDays--
    document.getElementById('dayText').classList.add('animate__flipInX')
    if ( theDays < 0 ) {
    console.log('homerun')
    theDays = 0
    theHours = 0
    theMinutes = 0
    theSeconds = 0
    clearInterval(theSecondsCount)
    }
    }
    setDays(theDays)
    setMinutes(theMinutes)
    setHours(theHours)
    }
            
    setMinutes(theMinutes)
    setSeconds(theSeconds)
    }  else {
    document.getElementById('minText').classList.remove('animate__flipInX')
    document.getElementById('hourText').classList.remove('animate__flipInX')
    document.getElementById('dayText').classList.remove('animate__flipInX')
    setSeconds(theSeconds)
    setMinutes(theMinutes)
    setHours(theHours)
    setDays(theDays)
    }
          
    }, 1000)
    }
    

    At first I was trying to recreate the card design pixel for pixel. It was a chore. I just so happened to right click the card group in figma and saw an option to copy the group as an svg.

    This is an excellent feature from figma. I took the svg that was generated and manipulated it until I was statisfied. I ended up using it as the background image for the number.

    <div id="daySvgContainer" className='flex justify-center items-center mb-[9px] bg-[url("/src/images/flip-sm.svg")] lg:bg-[url("/src/images/flip-lg.svg")] lg:h-full lg:mb-4'>
    
  • Submitted

    Age Calculator

    • HTML
    • CSS
    • JS

    0


    This project was very rewarding for me. It really pushed me several times. I could have mailed it in but I kept pushing. When I was finished, I went live only to find out that I had several mobile and safari browser issues. The issues surrounded how I was formatting the date. I am glad to have pounded through this. I feel like I am a better developer because of it.

  • Submitted

    BMI

    • HTML
    • CSS
    • JS

    0


    Styling the radio buttons was the first challenge in this project. I leaned about the appearance and accent-color properties. Also how to require a change on hover, a different change on checked and another different change on checked&hovered. Here is my rather long tailwindcss for an input in this project:

    <input name='selection' type="radio" id='metric' value='metric' className='mr-[18px] w-[31px] h-[31px] appearance-none rounded-[50%] border border-solid border-borders checked:bg-blue checked:border-[8px] checked:border-solid checked:border-[#d8e2e7] hover:border-blue checked:hover:bg-blue checked:hover:border-[#d8e2e7]'/>
    

    The next challenge that has been difficult is while in tablet view how to keep the image scaled correctly and not sacrifice a piece of the image. I am using object-fit: cover on the image and it scales nicely. However, the rounded edges of the image are not visible. If I allow do not use object-fit: cover then the rounded edges are visible but the image does not scale correctly.

    I got a lot of practice with passing props between components with this project. I am still not where I want to be but I am becoming more comfortable with it. Another thing I was able to do was to use a conditional inside of the return of a component. I've done this before but was able to use it this time for a solution to a problem was having. Here is the code:

    return (
        <>
    <div id="bottomResultsContainer" className='p-8 bg-blue rounded-2xl flex flex-col md:rounded-[16px_999px_999px_16px] md:h-[185px] md:flex-wrap md:justify-center'>
    {isNaN(userBMI) ? (
          <>
    <div id="welcomeContainer">
    <div id="welcomeHeading" className='font-["Inter"] text-white text-2xl tracking-[-1.2px] font-semibold mb-4'>
    <h1>Welcome!</h1>
    </div>
    <div id="welcomeCopy" className='font-["Inter"] text-white text-sm leading-[150%] font-normal'>
    <p>Enter your height and weight and you’ll see your BMI result here</p>
    </div>
    </div>
    </>
    ): (
          <>
    <div id='resultsHeading' className='font-["Inter"] font-semibold leading-[150%] text-white md:w-[50%] md:pb-2 xl:text-base xl:leading-[150%]'>
    <p>Your BMI is...</p>
    </div>
    <div id='resultsNumber' className='font-["Inter"] mb-6 text-5xl font-semibold leading-[110%] tracking-[-2.4px] text-white md:w-[50%] md:mb-0 md:pb-4 xl:text-[64px] xl:tracking-[-3.2px] xl:pb-0'>
    <p>{isNumber()}</p>
    </div>
    <div id='resultsInfo' className='font-["Inter"] text-sm font-normal leading-[150%] text-white md:w-[50%]'>
    <p>{bmiOutput()}<span className='font-semibold'>{idealWeight()}</span></p>
    </div>
    </>
    )}
    </div>
    </>
    )
    
  • Submitted


    It was good to have more practice with passing props from parent to child and back up. This project allowed me to pass from parent to child to child and then back up. I am gaining more of an understanding of the concept.

    I am still looking for the best method to handle the height of the app, so that it fills the entire screen without scrollbars. I used margins for this project, which works for some heights but not when the screen height exceeds the height of the entire app.

  • Submitted


    I fixed the issue I was having with the elements moving while in a landscape view. I had height at 100vh when getting to larger width screens. This seems to work great but when the page does not have enough height then the elements move around.

    I would like help with how to correctly fill the entire screen. Height at 100vh seems to look good but it causes a bunch of problems (other than the one above). If I don't declare a height then a giant white strip remains at the bottom of the page. I set the height of the entire app at 1002px this time. But if there is a taller screen than this then the white strip will appear.

    Bottom line are 2 things:

    1. How to display the entire app without scrollbars for all screen sizes.
    2. How to display the entire app without a white bottom for all screen sizes.
  • Submitted

    Intro form

    • HTML
    • CSS
    • JS

    1


    The first useful thing I learned was the ability to place a background image and background color on the same element. Previously I had been creating extra divs, moving them around and adjusting opacity. But the below code works just fine:

    <div id='wrapper' className='h-full bg-[url("./images/bg-intro-mobile.png")] bg-orange pt-[88px] px-6 pb-[68px] xl:px-0 xl:py-[121px] xl:flex xl:flex-col xl:flex-wrap xl:items-center'>
    

    I spent a lot of time trying to better understand React Hook Form during this project. I ran up against the default browser vaildation widget again. Previously I could work around it but with so many fields in this project the work around was not the best route. Finally I gave up and googled "chrome validation widget prevents react hook form from working on email fields". That search term was a winner and brought me to this page with the solution. It is very simple and I am happy to be done with this issue forever. Here is a SS of the error from the browser:

    Here is the simple code that fixes it and allows the code from React Hook Form to do its job:

    <form noValidate onSubmit={handleSubmit(onSubmit, onError)}>
    

    The last thing I learned was how to change the text color dynamically. Set the original text color and change the text color when an error it triggered. Simple enough. But how to change the text color back to the original color when the user begins to change the input? Listener waiting for the input event was the key here:

    function onError(e) {  
    // When an error occurs then for each error find the warning div for that field and display it
    for (const error in e) {
    let errorText = document.getElementById(error);
    console.log(errorText.value)
    errorText.style.color = '#FF7979'
    let errorElement = document.getElementById(error).parentElement.nextSibling
    errorElement.style.display = 'block'
    // Listen for when the user begins to fix the input and change the color of the text back to black
    errorText.addEventListener('input', function(){
    console.log('change')
    errorText.style.color ='#3D3B48'
    })
    }
    }
    
  • Submitted


    The first thing I learned was how to control the deg of a linear gradient with TailwindCSS. In the tailwind.config.js file I define what I want the gradient to look like. Then call that gradient where needed.

    theme: {
    extend: {
    backgroundImage: {
    'gradient-150': 'linear-gradient(150deg, #FFF 0%, #FFF4F4 100%);'
    }}}
    
    <div id='contentWrapper' className='pt-8 pb-[92px] bg-gradient-150 h-full'>
    

    Using the rgba color model you are able to change the opacity with the last value. This project called for the opacity of the border color to be 50%. I was able to set it to that value on initial load with Tailwind using this code:

    <div id="formContainer" className='flex items-center justify-between border border-solid border-darkPink/[.50] rounded-[28px] bg-transparent'>
    

    If the data as incorrectly entered then a new border color is shown. From here if a vaild email is then submitted I needed to revert all changes back to the original state. I used this code to get the opacity back to 50%:

    const formContainer = document.getElementById('formContainer');
    const clearText = document.getElementById('email');
    const warningContainer = document.getElementById('warningContainer');
    
    errorDiv.innerHTML = '';
    setNewError(errorDiv.innerHTML);
    clearText.value = ''
    warningContainer.style.display = 'none'
    formContainer.style.borderWidth = '1px'
    formContainer.style.borderColor = 'rgba(206, 152, 152, 0.5)'
    
  • Submitted

    Article Preview

    • HTML
    • CSS
    • JS

    0


    Traversing the DOM with JS is becoming easier for me and I am excited about it. That understanding seems to unlock a world of potential. For instance, with this project I was able to traverse and then utilize the width of an element to dicate when tooltip should show as a tooltip or just replace the content already on the page.

    // click on normal view
    function handleClick(e) {
    // check content width
    let contentWidth = getComputedStyle(document.getElementById('contwentWrapper')).maxWidth;
    contentWidth = contentWidth.split('px')
    contentWidth = contentWidth[0]
    contentWidth = parseInt(contentWidth)
            
    if (contentWidth < 730) {
    // grab the div containing all the info
    const hideDiv = e.target.parentElement.parentElement.parentElement
    // grab the hidden div
    const showDiv = hideDiv.nextSibling
    // change the div with all info to display none
    hideDiv.style.display = 'none';
    // change the hidden div to display flex
    showDiv.style.display = 'flex';
    } else {
    // change the icon
    const clickedIcon = e.target;
    const clickedIconParent = clickedIcon.parentElement.parentElement;
    const hiddenDiv = clickedIconParent.nextSibling;
    clickedIconParent.style.display = 'none';
    hiddenDiv.style.display = 'flex';
    
    // Display the tooltip
    const toolTip = document.getElementById('socialToolTip');
    toolTip.style.display = 'flex'
    }
    }
    

    Another thing I learned was how to utilize the transform property. I was able to get the tooltip to remain centered no matter the width of the page (in desktop views). This has been something that has given me a hard time on recent projects.

    <div id="socialToolTip" className='hidden absolute flex w-[248px] justify-between bg-darkBlue px-[37px] py-[18px] rounded-[10px] items-center top-[50%] left-[50%] translate-x-[77%] translate-y-[0%]'>
    

    So of my code for this solution is redundant or not needed. I found better ways to get to the same result as I progressed through the project and am not interested in removing the code first used for fear that it would cause a world of hurt.

  • Submitted

    Faq accordion

    • HTML
    • CSS
    • JS

    0


    I am still learning and trying to understand positioning. The app looks good when at views that have specific positioning rules applied. But making the screen larger or smaller from those views does not work as I would want.

    Javascript for this app was good practice. I began to further grasp the importance of declaring a variable before updating it later in the code. In the below code currentAnswerDiv is delcared as null before the icons loop.

    let currentAnswerDiv = null;
    
    icons.forEach((icon) => {
    icon.addEventListener('click', (event) => {
    let answerDiv = icon.parentElement.nextSibling;
    let question = icon.previousSibling.parentElement;
    
    if (currentAnswerDiv === answerDiv) {
    // The same answerDiv is clicked, so close it
    answerDiv.classList.add('hidden');
    question.style.fontWeight = 400;
    icon.style.transform = 'rotate(0deg)';
    currentAnswerDiv = null;
    } else {
    // A different answerDiv is clicked, so close the current one and open this one
    if (currentAnswerDiv !== null) {
    let currentOpen = currentAnswerDiv.parentElement.firstChild
    let currentIcon =currentOpen.firstChild.nextSibling
    currentAnswerDiv.classList.add('hidden');
    currentOpen.style.fontWeight = 400;
    currentIcon.style.transform = 'rotate(0deg)';
    }
    answerDiv.classList.remove('hidden');
    question.style.fontWeight = 700;
    icon.style.transform = 'rotate(180deg)';
    currentAnswerDiv = answerDiv;
    }
    });
    });
    

    Next a condition is run to check if the click event happened on the same question that is already opened and if it did then reset currentAnswerDiv to null.

    if (currentAnswerDiv === answerDiv) {
    // The same answerDiv is clicked, so close it
    answerDiv.classList.add('hidden');
    question.style.fontWeight = 400;
    icon.style.transform = 'rotate(0deg)';
    currentAnswerDiv = null;
    }
    

    A second condition is run to see if a different icon than then the one opened has been clicked, and close it if it has. Saying currentAnswerDiv !== null confirms that the currentAnswerDiv is being utilized and therefore an answer is being shown.

    else {
    // A different answerDiv is clicked, so close the current one and open this one
    if (currentAnswerDiv !== null) {
    let currentOpen = currentAnswerDiv.parentElement.firstChild
    let currentIcon =currentOpen.firstChild.nextSibling
    currentAnswerDiv.classList.add('hidden');
    currentOpen.style.fontWeight = 400;
    currentIcon.style.transform = 'rotate(0deg)';
    }
    

    Finally, the changes are applied to the question/answer that was clicked.

    answerDiv.classList.remove('hidden');
    question.style.fontWeight = 700;
    icon.style.transform = 'rotate(180deg)';
    currentAnswerDiv = answerDiv;
    
  • Submitted


    This challenge presented a few problems for me. The mobile view contains a masked background image and it was the first time I've encountered something like this. I was able to solve it by creating a background wrapper div that sits along side the main content div. Then I utilized positioning and opacity to lay one bg on top of the other. Here is the code:

    <div id='backgroundWrapper' className='absolute w-full md:flex md:justify-end'>
    <div id='backgroundImg' className='bg-[url("./assets/mobile/image-host.jpg")] md:bg-[url("./assets/tablet/image-host.jpg")] xl:bg-[url("./assets/desktop/image-host.jpg")] h-screen md:h-[767px] md:w-[491px] md:absolute md:bg-no-repeat md:z-10 xl:w-[888px] xl:h-[640px] xl:mt-[130px]'></div>
    <div id='background' className='h-screen opacity-[0.7992919683456421] bg-darkBlue absolute w-full bottom-0 md:hidden'></div>
    </div>
    

    Another challenge was the form validation. Although I believe that I made it more complicated than it needed to be. I was able to utilize react-hook-form to validate after the submit button was clicked and if the field is empty, and I used a custom function to validate after the submit button was clicked and if the field contains data. The most tricky part was disabling the browser default form validation widget. It was super annoying that the browser code was sitting in front of my code and would not let my code run. Specifically I had to prevent the default behavior on an invalid event. Here is the code:

    useEffect(() => {
    var input = document.getElementById('email');
    setInput(input)
            
    input.addEventListener('invalid', function(event) {
    event.preventDefault();
    console.log(event.target.value)
                
    if(isEmailValid(event.target.value)) {
    console.log('true')
    } else {
    console.log('false')
    const errorMsg = document.getElementById('errorP');
    errorMsg.innerHTML = 'Oops! Please check your email'
    console.log(errorMsg)
    
    }
                
    })
            
    },[])
    

    The final issue had to do with the height of the page and the footer section. If the height was not large enough then a white space would appear at the bottom of the page. This was because I placed the footer position as relative so that I could absolutely position the image at large screen size. I fixed this by giving the footer a defined height.

    <div id='footer' className='hidden md:block md:bg-darkBlue md:order-5 xl:right-0 xl:bottom-[125px] xl:z-40 xl:bg-transparent xl:relative xl:w-full xl:h-[232px]'>
    <Footer />
    </div>
    
    function Footer() {
    return (
        <>
    <img src={Dots} alt='dots' className='xl:absolute xl:top-[58px] xl:right-[-94px]' />
    </>
    )
    }
    
  • Submitted


    Using React useState, I was able to pass data between components. This was one of the first practical times I have had to utilize props and it helped me to understand the concept by putting it into practice. See the readme for more information.

  • Submitted


    I learned a little bit more about positioning elements on the right edge so that they do not create a scrollbar if they are too large.

    I learned that declaring the width of the parent element and then using overflow hidden will clip the image at the width of the parent container. This was great for me to learn. However, due to absolute position and then moving the element with top and left the image does not scale correctly. I can not figure out how to get the image to scale and utilize overflow hidden at the same time. Either the image creates a scrollbar (overflow not hidden) or the image does not scale (absolute position, left and top).

    Would like feedback on this.