This is a solution to the Note-taking web app challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
Users should be able to:
- Create, read, update, and delete notes
- Archive notes
- View all their notes
- View all archived notes
- View notes with specific tags
- Search notes by title, tag, and content
- Select their color theme
- Select their font theme
- Receive validation messages if required form fields aren't completed
- Navigate the whole app and perform all actions using only their keyboard
- View the optimal layout for the interface depending on their device's screen size
- See hover and focus states for all interactive elements on the page
- Bonus: Save details to a database (build the project as a full-stack app)
- Bonus: Create an account, log in, change password (add user authentication to the full-stack app)
- Bonus: Reset their password (add password reset to the full-stack app)
- Solution URL: Notes-solution-link
- Live Site URL: Notes-live-link
- Semantic HTML5 markup
- SCSS custom properties
- Flexbox
- CSS Grid
- Mobile-first workflow
- Pinia - State manager for Vue.js
- Vue.js - JavaScript framework
- Vue-router - For routing in Vue app
- Element-plus - UI library
- Firebase - For auth and store
In this project, the most challenging task was organizing the routes, as they needed to look different on mobile and desktop layouts. Additionally, I had to write an authentication guard while ensuring that the reset password page, which opens from a user’s email, was properly handled. This forced me to revise my authentication logic multiple times.
I also decided to use Firebase Hosting instead of Vercel, even though Vercel offers a much simpler deployment process compared to Firebase. However, it was really interesting to bind the GitHub repository with Firebase Hosting.
Auth guard function, see below:
export const authGuard = (
to: RouteLocationNormalized,
from: RouteLocationNormalizedLoadedGeneric,
next: NavigationGuardNext,
) => {
const userStore = useUserStore();
const isLoggedIn = userStore.isLogin;
const hasResetCode = to.query.oobCode || to.query.mode === "resetPassword";
if (hasResetCode) {
const resetParams = {
oobCode: to.query.oobCode,
mode: to.query.mode,
};
next({ path: "/reset-password", query: resetParams });
return;
}
if (to.meta.requiresAuth && !isLoggedIn) {
next({ name: "login" });
return;
}
if (!to.meta.requiresAuth && isLoggedIn) {
next({ name: "home" });
return;
}
next();
};For my next project, I plan to use vanilla JavaScript because I believe that understanding native technology is always a good idea. Frameworks are just JavaScript, and having strong fundamental knowledge is crucial. Therefore, I want to keep my skills sharp and my mind engaged by working directly with the core language.
- Dispatch Event - This helped me to overcome Element plus tags trigger logics. There was note to set trigger on comma an I neded to emulate behavior.
- SVG loader - It makes work with svg simpler and handy.
- Website - Dmytro Voitovych
- Frontend Mentor - @dmytrovoitovych







