Coder Social home page Coder Social logo

chaitra-kamath / seedfund Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tjtaylorjr/seedfund

0.0 1.0 0.0 667 KB

Seedfund is a Kickstarter clone demo site built with Python, Flask and React.

Home Page: https://seedfund-app.herokuapp.com

Shell 0.28% Python 49.16% CSS 47.99% HTML 1.29% Mako 0.58% Dockerfile 0.70%

seedfund's Introduction

SeedFund


Table of Contents




Description

A crowdfunding site in the style of Kickstarter. Currently, users can create projects and pledge money to ideas they like. Improvements and additional features to follow.





Application Architecture

SeedFund is a streamlined fullstack application built with PostgreSQL and Flask at the backend, which accepts RESTful data requests from the front-end user interface powered by React.


AppArchetecture




Frontend Overview


SeedFund was designed with simplicity in mind, allowing the frontend to focus on rendering served database records. However, future improvements such as messaging and project campaign rewards will make fuller use of React's powerful ability to maintain state.


React

React components simplify development and allow for the reuse of code while still keeping it dry. This is exemplified in SeedFund through the project card component. We have made use of this single page of code in different ways throughout the entire app.

The project card represents the benefit and disadvantages to using React all at once. Once challenge that we had to overcome was the split second flicker that can happen with React's useEffect hook. In this case, the app was rendering the default picture before the component could be updated with the picture from the database. There were several ways we could have addressed this problem but ultimately applied a loading animation to reveal the rendered component underneath after the DOM had been updated.


Framer Motion

To implement this solution, we brought in Framer Motion; It is an easy to use motion library that simplifies the work needed in CSS to achieve animation effects. We have posted the implementation of this library below:


loading animation component
import React, { useEffect, useRef } from "react";
import { motion } from "framer-motion";

const spinnerAnimation = {
  repeat: 2,
  repeatType: "loop",
  duration: 1.25,
  ease: "linear"
};

const LoadingAnimation = (props) => {

  const containerRef = useRef();
  const animationRef = useRef();

  const containerStyle = `spinnerContainer--${props.size}`;
  const animationStyle = `spinner--${props.size}`

  useEffect(() => {
    containerRef.current.classList.add(containerStyle);
    animationRef.current.classList.add(animationStyle);
  }, [])

  return (
    <div className="spinnerContainer" ref={containerRef}>
      <motion.span className="spinner"
        ref={animationRef}
        animate={{ rotate: 360}}
        transition={spinnerAnimation}
        />
    </div>
  );
};

export default LoadingAnimation;
Relevant CSS for component
.loadSpinner {
  position: absolute;
  transition: opacity 0.1s;
  height: 100%;
  width: 100%;
}

.loadSpinner--hide {
  opacity: 0;
}

.spinnerContainer  {
  position: relative;
  background-color: #FFFFFF;
  width: 100%;
  top: 0;
  left: 0;
  transition: opacity 0.1s;
}

.spinnerContainer--MED {
  height: 210px;
}

.spinner {
  display: block;
  border: solid #E8E8E8;
  border-top: solid #028858;
  border-radius: 50%;
  position: absolute;
  box-sizing: border-box;
}

.spinner--MED {
    top: 75px;
    left: 146px;
    width: 6rem;
    height: 6rem;
    border-width: 1rem;
}
Parent component implementation
    <>
      <div className="projectcard">
        <div>
          <div className="projectcard__wrapper">
            <div className="projectcard__container">
              <div className="projectcard__picturebox">
                <NavLink
                  to={"/project/" + project.id}
                  className="projectcard__picturebox-navlink"
                >
                  <div ref={spinnerRef} className="loadSpinner">
                    <LoadingAnimation size={"MED"} />
                  </div>
                  <div
                    style={
                      project.image
                        ? { backgroundImage: `url(${project.image})` }
                        : { backgroundImage: `url(${default_img})`}
                    }
                    className="projectcard__picture"
                  ></div>
                </NavLink>
              </div>
              <div>
                <div className="projectcard__topdata">
                  <div className="projectcard__topdata-text-container">
                    <NavLink
                      to={"/project/" + project.id}
                      className="projectcard__topdata-name"
                    >
                      <h3 className="projectcard__topdata-header">{project.title}</h3>
                      <p className="projectcard__topdata-desc">{project.description}</p>
                    </NavLink>
                  </div>
                </div>
                <div className="projectcard__topdata-creator">
                  <div style={{ display: "inline-block" }}>
                    <NavLink
                      to={{
                        pathname: "/discover/users/" + creator,
                        state: { creator_id: project.user_id },
                      }}
                      className="projectcard__topdata-creator-link"
                    >
                      <span>{"By " + creator}</span>
                    </NavLink>
                  </div>
                </div>
              </div>
              <div className="projectcard__bottomdata">
                <div className="projectcard__bottomdata-fillbar">
                  <div
                    className="projectcard__bottomdata-fillbar-progress"
                    style={fillBar(project.balance, project.funding_goal)}
                  ></div>
                </div>
                <div className="projectcard__bottomdata-campaign">
                  <div className="projectcard__bottomdata-pledged">
                    <span>{pledgeCount + " pledged"}</span>
                  </div>
                  <div className="projectcard__bottomdata-percent-funded">
                    <span>{funding}</span>
                  </div>
                  {remainingDays()}
                  <div className="projectcard__bottomdata-days">
                    <span className="projectcard__bottomdata-days-text">
                      {"End date: " + project.date_goal}
                    </span>
                  </div>
                  <div>
                    {project.category ? (
                      <NavLink
                        to={"/discover/" + project.category.toLowerCase()}
                        className="projectcard__bottomdata-category"
                      >
                        {project.category}
                      </NavLink>
                    ) : (
                        <NavLink
                          to={"#"}
                          className="projectcard__bottomdata-category"
                        >
                          Category
                        </NavLink>
                    )}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>

Backend Overview

SeedFund utilizes Python through the power of a Flask server with a PostgreSQL database to serve the front end. The entire operation is very straightforward with Flask facilitating data transfer to and from the user interface, updating data records in PostgreSQL as needed.

PostgreSQL

PostgreSQL's main draw is that it has 25 years of open source development behind it, making it one of the most stable and professional open source databases out there. Can't beat free and PostgreSQL is not lacking in features or power. It can handle high amounts of traffic which this app could certainly see, if it were in public use.

Flask

Flask is a micro framework that uses Python. This means it is light weight, easy to set up, and powerful. Flask's barebones approach allows you to not have to worry about bloat in your app and scale up as needed. This translates into a faster, more responsive application for your users.

A challenge that presented itself during this project was how the search route interacted with parameters passed from the front end. In particular, clicking on a quick select bar item that had an ampersand in it was causing a bad request error. Interestingly enough, the query parameter didn't even include an ampersand. Instead it was converting that into a space and making a fetch request to the backend for each word.

The front end loops were inefficient and it was unclear why this particular error was only happening with the quick select bar. If you typed the same query into the search bar, it would not produce an error. Our solution to this was to pass our query in a single fetch request with the '+' character standing in for any spaces. On the backend, we split the query and iterate through a list of parameters to return a dictionary of the combined results.


@project_routes.route('/search/<query>')
def searchForProjects(query):

    search_terms = query.split('+')

    result = list(chain.from_iterable(
                     (Project.query.filter(or_(
                         Project.title.ilike(f"%{term}%"),
                         Project.description.ilike(f"%{term}%"),
                         Project.category.ilike(f"%{term}%")
                     )).options(joinedload(Project.user)).all())
                     for term in search_terms))

    data = [project.to_dict() for project in result]

    return {"projects": data}

Conclusion and Next Steps

What we have built here is just the beginning. We have plans to add additional features to better reflect what crowdfunding applications can and should do.

Ultimately this was an enjoyable project that demonstrated just how easily and quickly the Flask/React stack can bring a job from concept to working software.




Team

Corbin Armendariz James Lee Miguel Munoz TJ Taylor
Corbin Armendariz James Lee Miguel Munoz TJ Taylor
github.com/corbinHA github.com/JamestLee513 github.com/memg92 github.com/tjtaylorjr

seedfund's People

Contributors

tjtaylorjr avatar memg92 avatar jamestlee513 avatar corbinha avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.