Skip to content
  • Unlock Pro
  • Log in with GitHub
Profile
OverviewSolutions
17
Comments
18

Pai-Kai Lee

@PaiKai-LeeTaiwan320 points

I’m a mysterious individual who has yet to fill out my bio. One thing’s for certain: I love writing front-end code!

Latest solutions

  • Product list with cart solution

    #react#tailwind-css

    Pai-Kai Lee•320
    Submitted about 2 months ago

    1 comment
  • Results summary component solution

    #tailwind-css#vite#react

    Pai-Kai Lee•320
    Submitted 2 months ago

    1 comment
  • News homepage solution


    Pai-Kai Lee•320
    Submitted 3 months ago

    2 comments
  • Contact form solution


    Pai-Kai Lee•320
    Submitted 3 months ago

    1 comment
  • FAQ accordion solution with navigating by keyboard

    #tailwind-css

    Pai-Kai Lee•320
    Submitted 4 months ago

    1 comment
  • Interactive rating component solution

    #tailwind-css#accessibility

    Pai-Kai Lee•320
    Submitted 4 months ago

    1 comment
View more solutions

Latest comments

  • Snigdha Sukun•550
    @snigdha-sukun
    Submitted 4 months ago
    What are you most proud of, and what would you do differently next time?

    I am proud of learning how to create & use React Context & Provider:

    interface CartContextType {
     products: Product[];
     cart: CartItemType[];
     addToCart: (product: Product) => void;
     removeFromCart: (productId: number) => void;
     emptyCart: () => void;
     findCartItem: (productId: number) => CartItemType | undefined;
     reduceQty: (product: Product) => void;
     increaseQty: (product: Product) => void;
     getTotalCost: () => number;
     isModalOpen: boolean;
     openModal: () => void;
     closeModal: () => void;
     resetCart: () => void;
    }
    
    export const CartContext = createContext<CartContextType | undefined>(
     undefined,
    );
    
    
    export const CartProvider: React.FC<{ children: React.ReactNode }> = ({
     children,
    }) => {
     const { products } = useFetchProducts();
    
     const [cart, setCart] = useState<CartItemType[]>([]);
     const [isModalOpen, setIsModalOpen] = useState(false);
    
     const openModal = useCallback(() => setIsModalOpen(true), []);
     const closeModal = useCallback(() => setIsModalOpen(false), []);
    
     const resetCart = useCallback(() => {
      setCart([]);
      closeModal();
     }, [closeModal]);
    
     const addToCart = useCallback((product: Product) => {
      setCart((prevCart) => {
       return [...prevCart, { ...product, quantity: 1 }];
      });
     }, []);
    
     const increaseQty = useCallback((product: Product) => {
      setCart((prevCart) => {
       return prevCart.map((item) =>
        item.id === product.id
         ? { ...item, quantity: item.quantity + 1 }
         : item,
       );
      });
     }, []);
    
     const reduceQty = useCallback((product: Product) => {
      setCart((prevCart) => {
       const updatedCart = prevCart
        .map((item) => {
         if (item.id === product.id) {
          const qty = item.quantity;
          if (qty === 1) {
           return null;
          }
          return { ...item, quantity: item.quantity - 1 };
         }
         return item;
        })
        .filter((item): item is CartItemType => item !== null);
       return updatedCart;
      });
     }, []);
    
     const removeFromCart = useCallback((productId: number) => {
      setCart((prevCart) => prevCart.filter((item) => item.id !== productId));
     }, []);
    
     const emptyCart = useCallback(() => {
      setCart([]);
     }, []);
    
     const findCartItem = useCallback(
      (productId: number) => {
       return cart.find((item) => item.id === productId);
      },
      [cart],
     );
    
     const getTotalCost = useCallback(() => {
      return cart.reduce((acc, item) => acc + item.price * item.quantity, 0);
     }, [cart]);
    
     const contextValue = useMemo(
      () => ({
       products,
       cart,
       addToCart,
       removeFromCart,
       emptyCart,
       findCartItem,
       reduceQty,
       increaseQty,
       getTotalCost,
       isModalOpen,
       openModal,
       closeModal,
       resetCart,
      }),
      [
       products,
       cart,
       addToCart,
       removeFromCart,
       emptyCart,
       findCartItem,
       reduceQty,
       increaseQty,
       getTotalCost,
       isModalOpen,
       openModal,
       closeModal,
       resetCart,
      ],
     );
    
     return (
      <CartContext.Provider value={contextValue}>{children}</CartContext.Provider>
     );
    };
    
    export const useCart = () => {
     const context = useContext(CartContext);
     if (!context) {
      throw new Error("useCart must be used within a CartProvider");
     }
     return context;
    };
    
    function App() {
    
     return (
      <ThemeProvider theme={theme}>
       <CartProvider>
        <GlobalStyles />
        <Container>
         <ProductList />
         <Cart />
        </Container>
        <OrderDialog />
       </CartProvider>
      </ThemeProvider>
     );
    }
    
    What specific areas of your project would you like help with?

    I still struggle with positioning certain UI elements. Like The "Add to Cart Button" in this challenge. Any tips or resources for learning that would be great!

    Product list with cart using React

    #react#styled-components
    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted about 2 months ago

    Your project structure and design are excellent — I’ve learned a lot from your work.

    1. You made great use of useCallback and useMemo in the context to optimize re-renders and avoid unnecessary computations.
    2. Separating the hooks and provider made the structure much cleaner and easier to maintain.
  • P
    mantis•390
    @morauszkia
    Submitted 5 months ago
    What are you most proud of, and what would you do differently next time?

    Building it with Vue.js was a challenge, because it was a while since I learned to use Vue. I was happy, that I managed to make everything work. Granted, this is an easier challenge, but one has to start somewhere :D

    What challenges did you encounter, and how did you overcome them?

    Defining the src attributes for the individual results dynamically. In the end I had to copy the svgs manually to the public folder, so now I have them duplicated. This works now, both in dev mode and production, but I am not satisfied with the hack.

    What specific areas of your project would you like help with?

    How should we point to static assets within the src folder so that after build the resources can be found by the app. Specifically, I am talking about the icons in ResultItem.vue. The paths come from the json file. I used relative paths from the ResultItem.vue component file to the svgs in the assets/images folder. After the build, the app was looking for the files in /assets/images, and couldn't find them. The build process did not copy the files to public. What did I miss?

    Results Summary component built with Vue.js

    #vue#vite
    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted 2 months ago

    Although I’m not very experienced with Vue, this looks nice and the code is clean.

  • Ayako•490
    @Ayako-Yokoe
    Submitted 3 months ago

    Using Grid and a Hamburger Menu with Animation

    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted 3 months ago

    Your layout and code is so clean, looks very nice ! I think I need to adjust my solution...

  • Kravchenko Evgeny•250
    @evgeniy8509
    Submitted 4 months ago

    Contact form

    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted 3 months ago

    Looks great, but I can't view your code. It's 404 github page.

  • P
    hcm•505
    @Hcmwebs
    Submitted over 1 year ago

    React and Tailwind/DaisyUI

    #react#tailwind-css
    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted 4 months ago

    Your project looks great so far! However, there are a couple of enhancements you could consider to improve accessibility and interactivity:

    1. Adding a tabindex attribute to the SingleQuestion component would enable better keyboard navigation, making it more accessible to users who rely on keyboards.

    2. Incorporating keyboard event listeners could enhance interactivity, allowing users to engage with the interface more seamlessly using key commands.

  • P
    Elewude Okikijesu•430
    @Helewud
    Submitted 4 months ago

    Interactive rating component HTML, CSS, JS

    #tailwind-css#accessibility
    1
    Pai-Kai Lee•320
    @PaiKai-Lee
    Posted 4 months ago

    looks nice. In my opinion one thing I will do is that add close button on dialog, this function is not in design but I think is good for UX, event it just a practice project.

    Marked as helpful
View more comments
Frontend Mentor logo

Stay up to datewith new challenges, featured solutions, selected articles, and our latest news

Frontend Mentor

  • Unlock Pro
  • Contact us
  • FAQs
  • Become a partner

Explore

  • Learning paths
  • Challenges
  • Solutions
  • Articles

Community

  • Discord
  • Guidelines

For companies

  • Hire developers
  • Train developers
© Frontend Mentor 2019 - 2025
  • Terms
  • Cookie Policy
  • Privacy Policy
  • License

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub