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
Plugins for Agisoft Metashape

Данные плагины предназначены для расширения функциональных возможностей Agisoft Metashape. Плагины представляют собой отдельные программы с собственным интерфейсом, которые запускаются внутри Agisoft

GeoScan 17 Dec 10, 2022
🤖🤖 Jarvis is an virtual assistant which can some tasks easy for you like surfing on web opening an app and much more... 🤖🤖

Jarvis 🤖 🤖 Jarvis is an virtual assistant which can some tasks easy for you like surfing on web opening an app and much more... 🤖 🤖 Developer : su

1 Nov 08, 2021
A simple countdown timer in eazy code to show timer with python

Countdown_Timer The simple CLI countdown timer in eazy code to show timer How Work First you fill the input by int-- (Enter the time in Seconds:) for

Yasin Rezvani 3 Nov 15, 2022
The program converts Swiss notes into American notes

Informatik-Programmieren Einleitung: Das Programm rechnet Schweizer Noten in das Amerikanische Noten um. Der Benutzer kann seine Note eingeben und der

2 Dec 16, 2021
Shutdown Time - A pretty much useless application that allows you to shut your computer down in x time with a GUI.

A pretty much useless application that allows you to shut your computer down in x time with a GUI. Should eventually support Windows (all versions), Linux (v2.0+), MacOS (probably with Linux, idk)

1 Nov 08, 2022
Awesome Cheatsheet

Awesome Cheatsheet List of useful cheatsheets Inspired by @sindresorhus awesome and improved by these amazing contributors. If you see a link here is

detailyang 6.5k Jan 07, 2023
The Python Fuzzer that the world deserves 🐍

pip3 install frelatage Current release : 0.0.2 The Python Fuzzer that the world deserves Installation | How it works | Features | Use Frelatage | Conf

Rog3r 219 Dec 21, 2022
Python’s bokeh, holoviews, matplotlib, plotly, seaborn package-based visualizations about COVID statistics eventually hosted as a web app on Heroku

COVID-Watch-NYC-Python-Visualization-App Python’s bokeh, holoviews, matplotlib, plotly, seaborn package-based visualizations about COVID statistics ev

Aarif Munwar Jahan 1 Jan 04, 2022
Create N Share is a No Code solution which gives users the ability to create any type of feature rich survey forms with ease.

create n share Note : The Project Scaffold will be pushed soon. Create N Share is a No Code solution which gives users the ability to create any type

Chiraag Kakar 11 Dec 03, 2022
Datargsing is a data management and manipulation Python library

Datargsing What is It? Datargsing is a data management and manipulation Python library which is currently in deving Why this library is good? This Pyt

CHOSSY Lucas 10 Oct 24, 2022
Enjoy Discords Unlimited Storage

Discord Storage V.3.5 (Beta) Made by BoKa Enjoy Discords free and unlimited storage... Prepare: Clone this from Github, make sure there either a folde

0 Dec 16, 2021
Load dependent libraries dynamically.

dypend dypend Load dependent libraries dynamically. A few days ago, I encountered many users feedback in an open source project. The Problem is they c

Louis 5 Mar 02, 2022
Open-source data observability for modern data teams

Use cases Monitor your data warehouse in minutes: Data anomalies monitoring as dbt tests Data lineage made simple, reliable, and automated dbt operati

889 Jan 01, 2023
Sample python script for monitoring Rocketchat database and get statistics of users.

rocketchat-DB-monitoring Sample python script for monitoring Rocketchat database and get statistics of users. 1. Update python: yum check-update && yu

Mojtaba Taleghani 1 Apr 12, 2022
Курс про техническое совершенство для нетехнарей

Technical Excellence 101 Курс про техническое совершенство для нетехнарей. Этот курс представлят из себя серию воркшопов, при помощи которых можно объ

Anton Bevzuk 11 Nov 13, 2022
An open source recipe book from the awesome staff of Clinical Genomics

meatballs An open source recipe book from the awesome staff of Clinical Genomics.

Clinical Genomics 2 Dec 07, 2021
A Bot that adds YouTube views to your video of choice

YoutubeViews Free Youtube viewer bot A Bot that adds YouTube views to your video of choice Installation git clone https://github.com/davdtheemonk/Yout

ProbablyX 5 Dec 06, 2022
A responsive package for Buttons, DropMenus and Combinations

A responsive package for Buttons, DropMenus and Combinations, This module makes the process a lot easier !

Skr Phoenix YT 0 Jan 30, 2022
A simple program to recolour simple png icon-like pictures with just one colour + transparent or white background. Resulting images all have transparent background and a new colour.

A simple program to recolour simple png icon-like pictures with just one colour + transparent or white background. Resulting images all have transparent background and a new colour.

Anna Tůmová 0 Jan 30, 2022
Change ACLs for QNAP LXD unprivileged container.

qnaplxdunpriv If Advanced Folder Permissions is enabled in QNAP NAS, unprivileged LXD containers won't start. qnaplxdunpriv changes ACLs of some Conta

1 Jan 10, 2022