YourCity is a platform to match people to their prefect city.

Related tags

Miscellaneousyourcity
Overview

YourCity

YourCity is a city matching App that matches users to their ideal city. It is a fullstack React App made with a Redux state manager and a backend using Python, Flask, SQL-Alchemy, and PostgresSQL.

Table of Contents
1. Features
2. Installation
3. Technical Implementation Details
4. Future Features
5. Contact
6. Special Thanks

Technologies

Features

Sign Up and Login Pages

Sign Up Login

Splash Page

Discover and search for new cities Feed Page

Features Splash Features

Profile

Profile card about user and view cities Profile

Feed Tab

YourCity feed displays all cities Feed Page

View, Add, Edit, and Delete Cities

Single city of name, photos, insights City Page

Add a City

follow

Cancel adding city

follow

Edit a city

Edit City

Create, Read, Update, Delete City Insights

View Insights

follow

Add Insights

follow

Edit Insights

follow

Installation

To build/run project locally, please follow these steps:

  1. Clone this repository
git clone https://github.com/{github-handle}/{app-name}.git
  1. Install Pipfile dependencies and create the virtual environment
pipenv install
  1. Install npm dependencies for the /react-app
cd react-app
npm install
  1. In the / root directory, create a .env based on the .env.example with proper settings

  2. Setup your PostgreSQL user, password and database and ensure it matches your .env file

  3. Before running any flask commands, confirm you are in the pipenv virtual env. If not, run the command:

pipenv shell
  1. In the root folder, create the database by running in the terminal:
flask db init
  1. In the root folder, migrate tables to the database by running in the terminal:
flask db migrate
  1. In the root folder, seed the database by running in the terminal:
flask seed all
  1. Start the flask backend in the / root directory
flask run
  1. Start the frontend in the /react-app directory
npm start

Technical Implementation Details

City Validators

This is the first project I used flask and SQLAlchemy, and I didn't have much experience using the wtform validators. After reading documentation, I created Forms to validate required fields with DataRequired and the length of fields with the Length class by providing a min and max.

Code snippet is shown here:

class CityPostForm(FlaskForm):
    name = StringField('name', validators=[DataRequired(), city_exists, Length(min=1, max=80)])
    state = StringField('state', validators=[Length(min=0, max=50)])
    thumbnail_img = StringField('thumbnail_img', validators=[Length(min=0, max=800)])
    description = StringField('description', validators=[Length(min=0, max=1200)])
    user_id = IntegerField('user_id', validators=[DataRequired()])

The form is created from the POST route to create a city, and it is validated using the validators above. If any fields throw an error, then the form.validate_on_submit() will fail and return the errors from form.errors. The resulting errors are passed into a custom error handler that sends back each of the errors to the frontend to display to the user, e.g. 'Field is required' or 'Name field must be between 0 and 100 characters in length'.

@city_routes.route('/', methods=['POST'])
@login_required
def city_post():
        form = CityPostForm()
        form['csrf_token'].data = request.cookies['csrf_token']
        if form.validate_on_submit():
            city = City()
            form.populate_obj(city)
            try:
                db.session.add(city)
                db.session.commit()
                return city.to_dict()
            except:
                return throw_server_error()
        return throw_validation_error(form.errors)

Read More for Long Posts (Insights)

Posts for insights are can span an entire page, which is not ideal for user experience. In order to limit the length, I created a Read More and Show Less buttons to conditionally render the entire post and to hide the post. I was able to use the scrollHeight and offsetHeight of the textarea input to determine if the text was overfilling the container. If the scroll is greater than the offset, then the post is longer and a Read More button should appear.

The frontend uses the isOverflow state to initially determine if the post is overflowing.

const [showMore, setShowMore] = useState(false);
const [isOverflow, setIsOverflow] = useState(true);

  
useEffect(() => {
  const scrollHeight = document.getElementById(`insight__text_id-${insight.id}`)?.scrollHeight;
  const offsetHeight = document.getElementById(`insight__text_id-${insight.id}`)?.offsetHeight;

  if (scrollHeight && offsetHeight) {
    if (scrollHeight > offsetHeight) {
      setShowMore(false);
    } else {
      setShowMore(true);
      setIsOverflow(false);
    }
  }
}, [insight.id]);

The showMore state is used to conditionally render a short post and the entire post. If showMore is false the component will render a cut off post that has a Read more click event to toggle the state. When the Read more is clicked, showMore is set to true and the component now renders the entire post.

In addition the isOverflow is used to render Show less only if the post is overfilling the container.

{!showMore &&
  <>
    <p>
      <span>
        { username }
      </span>
      { insight.insight }
    </p>
    <p className={styles.text_dots}>...</p>
    <span 
      onClick={() => setShowMore(true)}
    >
      Read more
    </span>
  </>
}
{showMore &&
  <>
    <p>
      <span>
        { username }
      </span>  
      { insight.insight }
    </p>
    {isOverflow &&
      <span 
        onClick={() => setShowMore(false)}
      >
        Show less
      </span>
    }
  </>
}

City Reducer

One of my goals on this project was to create a simple reducer with slices of state for each table. Taking code from one of my previous projects, I refactored the code to create four actions. The SET_CITY action case is used for updating the store for the CRUD operations of CREATE, UPDATE, and READ.

The reducer for my City table is shown below:

export default function reducer(state = {}, action) {
  let newState = { ...state };
  switch (action.type) {
    case SET_CITY:
      newState[action.city.id] = action.city;
      return newState;
    case SET_ALL_CITIES:
      action.cities.forEach(city => {
          newState[city.id] = city;
      });
      return newState;
    case DELETE_CITY:
      delete newState[action.cityId];
      return newState;
    case UNLOAD_CITIES:
      newState = {}
      return newState;
    default:
      return state;
  }
}

Future Features

  1. Matches - match people with cities based on their question responses

  2. Search - search cities

  3. Edit Profile - users edit profile info and add banner

Contact

Nico Pierson

[email protected]

Special Thanks

Owner
Nico G Pierson
Software Engineer passionate about open-source projects. Background in Python and JavaScript/React.js. When I don’t code, I travel and drink coffee.
Nico G Pierson
Desafio Final do Mod1 do Bootcamp EDC - v2 usando a RAIS

IGTI - Bootcamp Engenheiro de Dados Cloud Módulo 1 - Desafio Final - RAIS 2020 Código do Desafio Final V2 do Bootcamp Engenheiro de Dados Cloud do IGT

Neylson Crepalde 17 Nov 02, 2022
sawa (ꦱꦮ) is an open source programming language, an interpreter to be precise, where you can write python code using javanese character.

ꦱꦮ sawa (ꦱꦮ) is an open source programming language, an interpreter to be precise, where you can write python code using javanese character. sawa iku

Rony Lantip 307 Jan 07, 2023
Get a link to the web version of a git-tracked file or directory

githyperlink Get a link to the web version of a git-tracked file or directory. Applies to GitHub and GitLab remotes (and maybe others but those are no

Tomas Fiers 2 Nov 08, 2022
Tools, guides, and resources for blockchain analysts to interface with data on the Ergo platform.

Ergo Intelligence Objective Provide a suite of easy-to-use toolkits, guides, and resources for blockchain analysts and data scientists to quickly unde

Chris 5 Mar 15, 2022
reproduces experiments from

Installation To enable importing of modules, from the parent directory execute: pip install -e . To install requirements: python -m pip install requir

Meta Research 15 Aug 11, 2022
script to analyze EQ decay using python

pyq_decay script to analyze EQ decay using python PyQ Decay ver 1.0 A pythonic script to analyze EQ aftershock decay using method of Omori (1894), Mog

1 Nov 04, 2021
An After Effects render queue for ShotGrid Toolkit.

AEQueue An After Effects render queue for ShotGrid Toolkit. Features Render multiple comps to locations defined by templates in your Toolkit config. C

Brand New School 5 Nov 20, 2022
Minimalist BERT implementation assignment for CS11-747

minbert Assignment by Zhengbao Jiang, Shuyan Zhou, and Ritam Dutt This is an exercise in developing a minimalist version of BERT, part of Carnegie Mel

Graham Neubig 51 Jan 03, 2023
NES development tool made with Python and Lua

NES Builder NES development and romhacking tool made with Python and Lua Current Stage: Alpha Features Open source "Build" project, which exports vari

10 Aug 19, 2022
WhyNotWin11 - Detection Script to help identify why your PC isn't Windows 11 Release Ready

WhyNotWin11 - Detection Script to help identify why your PC isn't Windows 11 Release Ready

Robert C. Maehl 5.9k Dec 31, 2022
Run-Your-Own Firefox Sync Server

Run-Your-Own Firefox Sync Server This is an all-in-one package for running a self-hosted Firefox Sync server. It bundles the "tokenserver" project for

Mozilla Services 1.7k Dec 30, 2022
Fried Chicken Programming Language

Fried-Chicken Fried Chicken Programming Language How To Run Once downloaded and opened, choose any file for code. Any file extensions work. Just make

Attachment Studios 9 Jul 11, 2022
A inspector to be able to view and edit Qt style sheet while an application is running

Qt Style Sheet Inspector An inspector widget to view and modify the style sheet of a Qt app at runtime. Usage In order to use the inspector widget on

ESSS 46 Dec 10, 2022
Simple package to make requests throughout Tor with circuit renewal.

AutoTor Table of Contents About the Project Contents Dependencies Getting Started Installation Coding Contributing About the Project Simple package to

Salvador Belenguer 6 Jan 01, 2023
Custom Weapons 3 attribute support for Custom Weapons X

CW3toX Allows use of Custom Weapons 3 attributes in Custom Weapons X. Requiremen

2 Mar 01, 2022
Tools for collecting social media data around focal events

Social Media Focal Events The focalevents codebase provides tools for organizing data collected around focal events on social media. It is often diffi

Ryan Gallagher 80 Nov 28, 2022
Mengzhan (John) code for Closed Loop Control system of Sharp Wave Ripples in Hippocampus CA3 region

ClosedLoopControl_Yu Mengzhan (John) code for Closed Loop Control system of Sharp Wave Ripples in Hippocampus CA3 region Creating Python Virtual Envir

Mengzhan (John) Liufu 1 Jan 22, 2022
Understanding the field usage of any object in Salesforce

Understanding the field usage of any object in Salesforce One of the biggest problems that I have addressed while working with Salesforce is to unders

Sebastian Undurraga 1 Dec 14, 2021
TrainingBike - Code, models and schematics I've used to interface my stationary training bike with PC.

TrainingBike Code, models and schematics I've used to interface my stationary training bike with PC. You can find more information about the project i

1 Jan 01, 2022
A web interface for a soft serve Git server.

Soft Serve monitor Soft Sevre is a very nice git server. It offers a really nice TUI to browse the repositories on the server. Unfortunately, it does

Maxime Bouillot 5 Apr 26, 2022