linushuynh / Limontrello

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SVG Banners

Limontrello is a website inspired by Trello. Limontrello is a great tool for productivity and organizing tasks. Each user is able to make as many boards as they desire and within those boards they are able to make cards that can be labeled.

Limontrello also utilizes the React Beautiful DnD package to allow users to drag and drop cards.

Live Site: Limontrello

Frameworks, Platforms and Libraries:

JavaScript Python HTML5 CSS3 NodeJS Flask React Redux React Beautiful DnD

Database:

Postgres

Hosting:

Render

✅ Wiki Link

📷 Screenshots

Landing

image

Sign Up Page

image

Dashboard

Screenshot 2023-02-07 230651

Main Board View

Screenshot 2023-02-07 230920

Example Drag n Drop

Untitled video - Made with Clipchamp (3)

✂️ Code Snippets

Snippet 1 (Create board API route)

The following code is snipped from from API board routes and gets hit when a request to create a new board is sent to /api/boards

@board_routes.route('', methods=["POST"])
@login_required
def create_board():
    """
    Create a new board for the user and append 3 lists for the new board to
    start with
    """
    form = BoardForm()
    form["csrf_token"].data = request.cookies["csrf_token"]

    if form.validate_on_submit():
        data = form.data
        new_board = Board(
            name = data["name"],
            background = data["background"],
            private = data["private"],
            user_id = current_user.id
        )
        db.session.add(new_board)
        db.session.commit()

        # Add 3 default lists to newly created boards
        if len(new_board.lists) < 1:
            new_list1 = CardList(
                name = "To-Do",
                board_id = new_board.id
            )
            new_list2 = CardList(
                name = "In Progress",
                board_id = new_board.id
            )
            new_list3 = CardList(
                name = "Complete",
                board_id = new_board.id
            )
            new_board.lists.append(new_list1)
            new_board.lists.append(new_list2)
            new_board.lists.append(new_list3)
            db.session.add(new_board)
            db.session.commit()

        return new_board.to_dict()

    return {'error': validation_errors_to_error_messages(form.errors)}, 401

Snippet 2 (Create Card Component)

This snippet of code showcases the component responsible for proving the form to allow the user to create a new card

const CreateCardForm = ({ listId, setShowAddCardModal }) => {
    const [title, setTitle] = useState("")
    const dispatch = useDispatch()
    const currentUser = useSelector(state => state.session.user)
    const textRef = useRef(null)
    const { setHasSubmitted } = useContext(SubmittedContext)

    // Places text cursor and scrolls into view
    useEffect(() => {
        textRef.current.focus()
        textRef.current.scrollIntoView()
    }, [textRef])

    const closeCardForm = (e) => {
        e.preventDefault()
        setShowAddCardModal(false)
    }

    const submitNewCard = async (e) => {
        e.preventDefault()
            let input = {
                title,
                description: "",
                listId
            }
            setShowAddCardModal(false)
            await dispatch(createCardThunk(input, currentUser.id))
            setHasSubmitted(prev => !prev)
    }

    return (
        <div className={styles.formContainer}>
            <form className={styles.form}>
                <div className={styles.inputContainer}>
                    <input
                    value={title}
                    onChange={(e) => setTitle(e.target.value)}
                    placeholder="Enter a title for this card..."
                    className={styles.inputArea}
                    ref={textRef}
                    maxLength={100}
                    type="text"
                    />
                </div>
                <div className={styles.titleCount}>
                    {title.length}/100 characters
                </div>
                <div className={styles.buttonsContainer}>
                    <button type="submit" className={styles.addCardButton} onClick={submitNewCard}>Add card</button>
                    <button onClick={closeCardForm} className={styles.Xbutton}>
                        <span className="material-symbols-outlined">close</span>
                    </button>
                </div>
            </form>
        </div>
    )
}

💻 Run Limontrello on Local

Clone the project

git clone https://github.com/linushuynh/Limontrello.git

Install dependencies

cd react-app
npm install
cd ..
pipenv install -r requirements.txt
pipenv run
flask db upgrade
flask seed all

Setup the Environment Variables

To run this project, you will need to add a .env file in the root of your directory To do this, duplicate(copy/paste) the .env.example file in the root directory then rename the copy to .env Make sure the SECREY_KEY, DATABASE_URL, and SCHEMA are the same.

Start the backend of the server

pipenv run flask run

Open another terminal window(make sure you're in the root directory) then run

cd react-app
npm start

Then you can visit localhost:3000 to view your local version of Limontrello!

About


Languages

Language:CSS 53.9%Language:Python 44.8%Language:HTML 0.7%Language:Mako 0.5%Language:Shell 0.0%