Build a Recipe Box - my recipe book

Build a Recipe Box - my recipe book
0

Hi,

I completed the minimal user story at my recipebox challenge.

GitHub for code

Live page

Please test the functionality by focusing the user story.
Before I start the next challenge I want to take a big breath and continue to update this project.
I would like to create a fully usable website from this take home project.

My plan is:

  • create a registration/login procedure
  • create a database to store the new recipes
  • create an interface to see the recipes uploaded by someone else
  • user can upload any image, now only url can set as background
  • continue to develop the filters (I already added some icon to left side, these still not work. These icons will filter the recipes in the book, and the search icon(left side, already fully functional) will help to find quickly the recipe what we looking for… )
  • maybe I add more a forum for every recipes where the users can share their experience?
  • if you have any idea what else functionality sall I add more to the project, please write me a message
  • and at least the biggest challenge will be turn mobile responsive this challenge. The design what I choose is impossible to keep on mobile and the code is also difficult a bit to turn responsive with some media query code. Maybe I will rotate the book on mobile? At top will be the image and at bottom the content of recipe? Like any calendar. Or any idea?

I really like how your tabs pop into the screen when hovered over.

Very nice job @lendoo. One thing I noticed after hunting around was that there is the word ‘Next’ on the bottom left of each recipe. I only saw it clearly on the Easy Chocolate Pie recipe. Definitely make that a different color so it’s easier to be seen and maybe say ‘Next Recipe’. Along with that, maybe a ‘Previous Recipe’ link.

Pretty cool that you did it all in plain JS. Although I must say for this type of project I would suggest using a library/framework (React/Vue or whatever). I’m guessing it was great practice so that’s what really matters.

Now for some constructive criticism, not about the code, but about the UX.

I find the UX pretty unintuitive and confusing. I’d take a simple boring app that I can use, without having to think, any day of the week. Read the book Don’t make me think if you can. Good UX is hard, so don’t take it too badly.

  • The navigation of the recipes is almost hidden. How to go back from the final page is completely hidden and the action that takes you back is not the same that was used for navigating the recipes. If clicking the page is used for navigation it should be consistent throughout.

  • The mouse pointer should help guide the user when something is clickable.

  • The search is unintuitive and the most important part of the UI is hidden (the search box).

  • The interface for adding a new recipe is not very user-friendly. The action needed for adding the final recipe is unclear and so is canceling out of adding a new recipe.

  • Deleting a recipe is using an unclear confirmation step. I would suggest simply adding a text confirmation of the delete action. The action needed for canceling a delete action is unclear.

  • The edit mode is hard to find. If you are going to use icons for actions, make sure the icon actually represents the action.

  • What is recipesMenu used for? If it has no function, it’s just confusing. If it does have a function, I can’t figure it out.

I’m impressed by the work you put into the code. I just wish you had given the usability of the app a little more thought. If you really want a fully usable website then my main suggestion would be to improve usability, before all the other things you mentioned.

Hi,

Thank you for the review. I will correct every issues…
To the next/back button I added an animation. Now the color is animated between black and white. I cannot to set any static color because the user can set the background color and also image when add new recipe to the book. So always be any not visible color. Maybe this solution will be fine for all color.
I also added some new recipes to the book. Please go to the last page and reset the local storage to see the new recipes. Categories added to the recipes, the right side menu still not usable, but change the color of shadow depending of the current recipes.
At the last page I found any cross browser compatibility issue. With opera, chrome and edge works well. You can click anywhere at the back page to go back. But on Firefox not works :(.
It will hard to find the issue because there is not any error on console. I must log out the relevant variables from rows to rows to find the issue.
While I developed this project I found another compatibility issue, but I got error message, it was easy to resolve: the event object is a bit different on Firefox. It is not include path property but on other browser have event.path… strange…

Updated:
I tried to find the FireFox compatibility issue. If I right-click on the recipebook cover, and click on inspect Element: it is show me wrong page. Looks like any z-index issue but the z-index is all right. The first sheet is the highest… and decreased till the end. On other browser everything works well. If I change the dataset in the book (click on right menu or click on login book, everything works well.) Only with full dataset turn crazy the Firefox… Any idea?

For the recipe book navigation what I would suggest is moving the navigation out of the book. Maybe try adding arrow icons at each side of the book, or below each page, pointing in the logical direction.

The issue with Firefox does look like a CSS issue (stacking order/z-index).

Visually it looks correct, but as you know from inspecting it, the element is not on top. So the event handler is not fired because you are not actually clicking on the last page. The reset button doesn’t work in Firefox for the same reason. The back button stops working on the Easy Chocolate Pie page. So something is happening right there (or right before).

tl;dr:
Not sure what the best CSS solution to this problem is but setting the pages that are not “in view” to display: none does seem to fix it.

Long rambling

I can’t really figure out why it only breaks in Firefox but I suspect it may have to do with the stacking order (source order) and how you are changing the z-index. Some of the pages have the same z-index at different points when navigating. I think the layering might be switching from z-index to natural stacking order (source order) and back to z-index and that might be causing an issue. Not sure though, it’s a bit strange that it only breaks in Firefox.

The combination of stacking order, z-index and using transforms and other properties that create new stacking contexts does make it a bit challenging. It isn’t really helping that the styles are being applied the way they are.

I would likely have to look at some page flip examples to see what can be done. You can check the page on codrops they usually have some solid code. You can also look at some plugin code to see how they are doing it (or just use the plugin I guess).

Hi,
Because of the pandemic I have almost zero time to learn (I am a key-worker and must work a lot… ). But the registration/login form already done with a quite good client side validation. I wrote a class to reuse later the code.
Now I start to write the server side registration/login procedure.
It will also a huge challenge because my host have only PHP and I don’t want to upload the project to the Glitch. For real project it is too slow.
So I will use PHP with MySQL. I try to develop everything in OOP. Once I learned this technique (Data structures challenge on FCC) I see already how much easier to write reusable code with classes.
I never use classes in PHP before. I must learn almost everything from zero… Huge challenge waiting for me… :slight_smile:

Hi,

I created my first class ever in PHP.
The server side validation also done.

Maybe anyone can take a look it is safe or need more any addition action before create account?

class Validate
<?php

class Validate {
    // Properties:
    private $username;
    private $email;
    private $password;
    private $errorMessage;
    private $validData;
    
    function __construct($username, $email, $password) {
        $this->username = filter_var(trim($username), FILTER_SANITIZE_STRING);
        $this->email = filter_var(trim($email), FILTER_SANITIZE_EMAIL, FILTER_FLAG_NO_ENCODE_QUOTES);
        $this->password = filter_var(trim($password), FILTER_SANITIZE_STRING);
    }
    
    private function username($lenght = 1) {
        if (strlen($this->username) >= $lenght) {
            $this->validData["username"] = $this->username;
        } else {
            $this->errorMessage["username"] = "username too short";
        }
    }
    
    private function email() {
        if (filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
            $this->validData["email"] = $this->email;
        } else {
            $this->errorMessage["email"]  = "invalid email";
        }
    }
    
    private function password($lenght = 6) {
        if (strlen($this->password) >= $lenght) {
            $this->validData["password"] = $this->password;
        } else {
            $this->errorMessage["password"] = "password too short";
        }
    }
    
    public function getData($username = true, $email = true, $password = true) {
        if ($username) {
            $this->username();
        }
        if ($email) {
            $this->email();
        }
        if ($password) {
            $this->password();
        }
        $result["error"] = $this->errorMessage;
        $result["valid"] = $this->validData;
        return $result;
    }
}

?>
signup.php
<?php
session_start();
require_once("validate.php");
// declare variables:
$data = $username = $email = $password = ""; // user inputs
$result = "";

$data = json_decode($_POST["data"]);
//$data->username = "";
//$data->email = "lendoogmail.com";
$validate = new Validate($data->username, $data->email, $data->password);

$result = $validate->getData();
//var_dump($result);
if ($result["error"]) {
    exit(json_encode($result["error"]));
}

// all necessary data valid: create account


?>

Maybe I create more another method to encrypt password, and the getData() will send back the encrypted password, not the original…