8000 GitHub - ldldylan/PixelPanda
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ldldylan/PixelPanda

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pixel Panda

Pixel Panda is an innovative online marketplace that connects game artists with developers and buyers. Our platform offers a wide range of game assets, organized into categories for easy browsing. Users can add their favorite artworks to their shopping carts or save them to their wish lists for future reference. Our review system allows buyers to share their experiences and provide valuable feedback to artists, helping others make informed decisions when selecting assets. With the ability to write, edit, or delete reviews, users have complete control over their contributions to the Pixel Panda community.

Technologies

  • Frontend: React, Redux
  • Backend: Node, Express, MongoDB
  • AWS
  • Stripe

Highlightened Features

Categories

Create Artwork

Checkout

Hightlightened Code Snippets

Creating a Wishlist Item

router.post('/users/:userId', requireUser, validateWishlistItemInput, async (req, res, next) => {
    try {
        const newWishlistItem = new WishlistItem({
            user: req.params.userId,
            artwork: req.body.artwork
        });
        let wishlistItem = await newWishlistItem.save();
        wishlistItem = await wishlistItem.populate('user', 'artwork');
        return res.json(wishlistItem);
    }
    catch (err) {
        next(err);
    }
});

Uploading a Single File with AWS

const singleFileUpload = async ({ file, public = false }) => {
    const { originalname, buffer } = file;
    const path = require("path");
    const Key = new Date().getTime().toString() + path.extname(originalname);
    const uploadParams = {
        Bucket: NAME_OF_BUCKET,
        Key: public ? `public/${Key}` : Key,
        Body: buffer
    };
    const result = await s3.upload(uploadParams).promise();
    return public ? result.Location : result.Key;
};

Sending Information to the Stripe API

router.post('/', async (req, res) => {
    let success_url = `${process.env.CLIENT_URL}/checkout`;
    let cancel_url = `${process.env.CLIENT_URL}/cart`;
    const website = "https://pixelpanda.onrender.com";
    if (isProduction) {
        success_url = `${website}/checkout`;
        cancel_url = `${website}/cart`;
    }

    const session = await stripe.checkout.sessions.create({
        line_items: req.body.cartItems.map(cartItem => {
            return {
                price_data: {
                    currency: 'usd',
                    product_data: {
                        name: cartItem.name,
                        images: [cartItem.ArtworkImageUrl],
                    },
                    unit_amount: parseFloat((cartItem.price * 100).toFixed(2)),
                },
                adjustable_quantity: {
                    enabled: false,
                },
                quantity: 1,
            }
        }),
        submit_type: 'pay',
        mode: 'payment',
        payment_method_types: ['card'],
        success_url: success_url,
        cancel_url: cancel_url,
    });
    res.send(session);
});

Handling Frontend Validations for Creating Artwork

const handleSubmit = (e) => {
    e.preventDefault();
    if (image.length === 0) {
        alert('Please upload an image');
        return;
    }
    const formData = new FormData();
    const errorData = {
        name: "",
        description: "",
        price: "",
        category: ""
    };

    if (name.trim()) formData.append("name", name.trim());
    else errorData.name = "Please enter a name";

    if (description.trim()) formData.append("description", description.trim());
    else errorData.description = "Please enter a description";

    if (price && !isNaN(price) && price > 0 && price < 100000) {
        const formattedPrice = parseFloat(parseFloat(price).toFixed(2));
        formData.append("price", formattedPrice);
    }
    else errorData.price = "Please enter a valid price";

    formData.append("image", image);

    if (category) formData.append("category", category);
    else errorData.category = "Please select a category";

    formData.append("author", sessionUser._id)

    setErrors(errorData);

    if (errorData.name || errorData.description || errorData.price || errorData.category) return;
    else {
        dispatch(createArtwork(formData)).then(() => {
            if (updateShouldFetchArtworks) {
                updateShouldFetchArtworks(true);
            }
            setImage([]);
            setImageUrl([]);
            setPrice("0")
            setName('');
            setDescription('');
            setCategory("");
            fileRef.current.value = null;
            onClose();
            dispatch(fetchArtworks());
        });
    }

};

Handling Information for Reviews

const handleSubmit = (e) => {
    e.preventDefault();

    const reviewData = {
        ...review,
        content,
        rating,
        author,
        artworkId
    }
    setErrors([]);
    if (formType === "Edit Review") {
        dispatch(updateReview(reviewData,reviewId))
            .then(() => {
                history.push(`/artworks/${artworkId}`)
            })
    } else {
        dispatch(createReview({ artworkId, author, content, rating }))
            .then(() => {
                history.push(`/artworks/${artworkId}`)
            })
    }

}

Sending Information from the Frontend

export const checkoutCartItems = (cartItems) => async dispatch => {
    const stripe = await loadStripe(STRIPE_PUBLISHABLE_KEY);
    const res = await jwtFetch(`/api/stripe/`, {
        method: 'POST',
        body: JSON.stringify({ cartItems })
    })
    const session = await res.json();
    stripe.redirectToCheckout({ sessionId: session.id });
}

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  
0