From e0c5f60c68b2dc81839b36d40e7b9f2e75fd54f6 Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 7 Oct 2020 18:26:59 +0300 Subject: [PATCH 1/7] rename original gangsta to gang --- app/controllers/gangs_controller.rb | 28 +++++++++++++++++++ .../original_gangstas_controller.rb | 28 ------------------- app/models/gang.rb | 3 ++ app/models/original_gangsta.rb | 3 -- client/src/App.js | 20 ++++++------- client/src/cash/Cash.js | 4 +-- .../ChipSelection.js | 4 +-- client/src/homies/CashFlow.js | 6 ++-- client/src/homies/Flow.js | 4 +-- config/initializers/inflections.rb | 1 - config/routes.rb | 2 +- ...80902_rename_original_gangstas_to_gangs.rb | 5 ++++ db/schema.rb | 22 +++++++-------- 13 files changed, 67 insertions(+), 63 deletions(-) create mode 100644 app/controllers/gangs_controller.rb delete mode 100644 app/controllers/original_gangstas_controller.rb create mode 100644 app/models/gang.rb delete mode 100644 app/models/original_gangsta.rb rename client/src/{originalGangstaOnboarding => gangOnboarding}/ChipSelection.js (92%) create mode 100644 db/migrate/20201007180902_rename_original_gangstas_to_gangs.rb diff --git a/app/controllers/gangs_controller.rb b/app/controllers/gangs_controller.rb new file mode 100644 index 0000000..958b243 --- /dev/null +++ b/app/controllers/gangs_controller.rb @@ -0,0 +1,28 @@ +class GangsController < ApplicationController + def show + if Gang.count.zero? + Gang.create.save + end + + json_response Gang.first + end + + def update + if gang_params[:chip_scale].to_i.positive? + Gang.update(gang_params) + json_response onboarded: true + else + error_response :bad_request + end + end + + private + + def gang_params + params.require(:gang).permit :chip_name, + :chip_code, + :chip_symbol, + :chip_scale, + :chip_prefixed + end +end diff --git a/app/controllers/original_gangstas_controller.rb b/app/controllers/original_gangstas_controller.rb deleted file mode 100644 index 2d5debe..0000000 --- a/app/controllers/original_gangstas_controller.rb +++ /dev/null @@ -1,28 +0,0 @@ -class OriginalGangstasController < ApplicationController - def show - if OriginalGangsta.count.zero? - OriginalGangsta.create.save - end - - json_response OriginalGangsta.first - end - - def update - if original_gangsta_params[:chip_scale].to_i.positive? - OriginalGangsta.update(original_gangsta_params) - json_response onboarded: true - else - error_response :bad_request - end - end - - private - - def original_gangsta_params - params.require(:original_gangsta).permit :chip_name, - :chip_code, - :chip_symbol, - :chip_scale, - :chip_prefixed - end -end diff --git a/app/models/gang.rb b/app/models/gang.rb new file mode 100644 index 0000000..e2d3d62 --- /dev/null +++ b/app/models/gang.rb @@ -0,0 +1,3 @@ +class Gang < ApplicationRecord + +end \ No newline at end of file diff --git a/app/models/original_gangsta.rb b/app/models/original_gangsta.rb deleted file mode 100644 index a579514..0000000 --- a/app/models/original_gangsta.rb +++ /dev/null @@ -1,3 +0,0 @@ -class OriginalGangsta < ApplicationRecord - -end \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 2c8d82b..0ae860a 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -16,21 +16,21 @@ import { PUT_IN_WORK } from './RouteNames'; import PutInWork from "./cash/PutInWork"; -import ChipSelection from "./originalGangstaOnboarding/ChipSelection"; +import ChipSelection from "./gangOnboarding/ChipSelection"; import {errorToast} from "./common/errorHelpers"; const App = (props) => { const [loading, setLoading] = useState(true); - const [originalGangsta, setOriginalGangsta] = useState({}); + const [gang, setGang] = useState({}); useEffect(() => { (async() => { try { setLoading(true); - const response = await axios.get(`/api/original_gangstas/0`); + const response = await axios.get(`/api/gangs/0`); if (response.status === 200 && response.data){ - setOriginalGangsta(response.data); + setGang(response.data); }else{ errorToast(); } @@ -42,15 +42,15 @@ const App = (props) => { }, []); const routes = ([ - } />, - } />, - } />, - } />, - } /> + } />, + } />, + } />, + } />, + } /> ] ); - const onboarded = () => originalGangsta.chip_name && originalGangsta.chip_name.length > 0; + const onboarded = () => gang.chip_name && gang.chip_name.length > 0; const preloaderCircle = (
diff --git a/client/src/cash/Cash.js b/client/src/cash/Cash.js index 331591e..22f53ca 100644 --- a/client/src/cash/Cash.js +++ b/client/src/cash/Cash.js @@ -11,7 +11,7 @@ import M from 'materialize-css'; const Cash = (props) => { const [homiesCash, setHomiesCash] = useState([]); - const originalGangsta = props.originalGangsta; + const gang = props.gang; useEffect( () => { const getCashForHomies = async () => { @@ -49,7 +49,7 @@ const Cash = (props) => { { formatTime(homieLine.work) } - { formatMoney(homieLine.amount, originalGangsta) } + { formatMoney(homieLine.amount, gang) } [ diff --git a/client/src/originalGangstaOnboarding/ChipSelection.js b/client/src/gangOnboarding/ChipSelection.js similarity index 92% rename from client/src/originalGangstaOnboarding/ChipSelection.js rename to client/src/gangOnboarding/ChipSelection.js index 1bd167c..af7ee9a 100644 --- a/client/src/originalGangstaOnboarding/ChipSelection.js +++ b/client/src/gangOnboarding/ChipSelection.js @@ -31,7 +31,7 @@ const ChipSelection = (props) => { const handleSubmit = async () => { const chipData = chips.find(chip => chip.id === parseInt(selectedChip)); if (chipData){ - const originalGangsta = { + const gang = { chip_name: chipData.name, chip_code: chipData.code, chip_symbol: chipData.symbol, @@ -40,7 +40,7 @@ const ChipSelection = (props) => { } try{ - const response = await axios.put('/api/original_gangstas/0', { 'original_gangsta': originalGangsta }); + const response = await axios.put('/api/gangs/0', { 'gang': gang }); if (response.status === 200 && response.data && response.data.onboarded) { window.location.reload(); }else{ diff --git a/client/src/homies/CashFlow.js b/client/src/homies/CashFlow.js index 4694011..c71a229 100644 --- a/client/src/homies/CashFlow.js +++ b/client/src/homies/CashFlow.js @@ -7,7 +7,7 @@ import {errorToast} from "../common/errorHelpers"; const CashFlow = (props) => { const { homie_id } = useParams(); - const originalGangsta = props.originalGangsta; + const gang = props.gang; const [cashFlow, setCashFlow] = useState([]); @@ -35,7 +35,7 @@ const CashFlow = (props) => {
{ dateBlock(singleFlowData['created_at']) }
-
0 ? 'amount-green' : ''}`}>{ formatMoney(singleFlowData.amount, originalGangsta) }
+
0 ? 'amount-green' : ''}`}>{ formatMoney(singleFlowData.amount, gang) }
@@ -58,7 +58,7 @@ const CashFlow = (props) => { {`${totalCount} Records`}{` • ${fromDate} - ${toDate}`}
- Total cash flow: {formatMoney(totalFlow, originalGangsta)} + Total cash flow: {formatMoney(totalFlow, gang)}
diff --git a/client/src/homies/Flow.js b/client/src/homies/Flow.js index 78eb8f5..c2b2d9f 100644 --- a/client/src/homies/Flow.js +++ b/client/src/homies/Flow.js @@ -7,7 +7,7 @@ import WorkFlow from "./WorkFlow"; const Flow = (props) => { const [flowType, setFlowType] = useState('cash'); - const originalGangsta = props.originalGangsta; + const gang = props.gang; return (
@@ -19,7 +19,7 @@ const Flow = (props) => { />
- { flowType === 'cash' && } + { flowType === 'cash' && } { flowType === 'work' && } diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 9f8e25d..ab4f265 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -17,5 +17,4 @@ ActiveSupport::Inflector.inflections do |inflect| inflect.irregular 'work', 'work' - inflect.irregular 'gangsta', 'gangstas' end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 6ebc143..fa4ec00 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ Rails.application.routes.draw do constraints format: :json do scope :api do - resources :original_gangstas, only: [:show, :update] + resources :gangs, only: [:show, :update] resources :money_moves resources :work resources :chips, only: %i[index create destroy] diff --git a/db/migrate/20201007180902_rename_original_gangstas_to_gangs.rb b/db/migrate/20201007180902_rename_original_gangstas_to_gangs.rb new file mode 100644 index 0000000..68ccbc1 --- /dev/null +++ b/db/migrate/20201007180902_rename_original_gangstas_to_gangs.rb @@ -0,0 +1,5 @@ +class RenameOriginalGangstasToGangs < ActiveRecord::Migration[5.2] + def change + rename_table :original_gangstas, :gangs + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index e1a270a..28977bc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_10_06_120951) do +ActiveRecord::Schema.define(version: 2020_10_07_180902) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -35,6 +35,16 @@ ActiveRecord::Schema.define(version: 2020_10_06_120951) do t.index ["name"], name: "index_chips_on_name", unique: true end + create_table "gangs", force: :cascade do |t| + t.text "chip_name" + t.text "chip_code" + t.text "chip_symbol" + t.boolean "chip_prefixed" + t.integer "chip_scale" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "homies", force: :cascade do |t| t.text "name", null: false t.integer "importance", default: 100, null: false @@ -51,16 +61,6 @@ ActiveRecord::Schema.define(version: 2020_10_06_120951) do t.datetime "updated_at", null: false end - create_table "original_gangstas", force: :cascade do |t| - t.text "chip_name" - t.text "chip_code" - t.text "chip_symbol" - t.boolean "chip_prefixed" - t.integer "chip_scale" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "work", force: :cascade do |t| t.text "description" t.integer "amount" From 8d7716f2e0468ac9d1a67fe3a0d95d5c681da416 Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 7 Oct 2020 22:45:34 +0300 Subject: [PATCH 2/7] Show gang switch --- client/src/App.css | 4 ++ client/src/App.js | 47 ++++++++++++++----- .../{ChipSelection.js => GangOnboarding.js} | 24 +++++++--- client/src/homies/Homies.js | 2 +- client/src/homies/NewHomieForm.js | 7 ++- 5 files changed, 63 insertions(+), 21 deletions(-) rename client/src/gangOnboarding/{ChipSelection.js => GangOnboarding.js} (68%) diff --git a/client/src/App.css b/client/src/App.css index d5bdbce..2085026 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -54,4 +54,8 @@ position: absolute; height: 90%; margin-left: 40%; +} + +.bump { + margin-left: 2em; } \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index 0ae860a..8d7bb75 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import './App.css'; -import { Navbar } from 'react-materialize'; +import { Navbar, Dropdown, Icon } from 'react-materialize'; import MakeMoneyMove from './cash/MakeMoneyMove'; import Flow from "./homies/Flow"; import Cash from './cash/Cash'; @@ -16,21 +16,23 @@ import { PUT_IN_WORK } from './RouteNames'; import PutInWork from "./cash/PutInWork"; -import ChipSelection from "./gangOnboarding/ChipSelection"; +import GangOnboarding from "./gangOnboarding/GangOnboarding"; import {errorToast} from "./common/errorHelpers"; const App = (props) => { const [loading, setLoading] = useState(true); - const [gang, setGang] = useState({}); + const [gangs, setGangs] = useState([]); + const [selectedGang, setSelectedGang] = useState({}); useEffect(() => { (async() => { try { setLoading(true); - const response = await axios.get(`/api/gangs/0`); + const response = await axios.get(`/api/gangs`); if (response.status === 200 && response.data){ - setGang(response.data); + setGangs(response.data); + setSelectedGang(response.data[0]); }else{ errorToast(); } @@ -42,15 +44,15 @@ const App = (props) => { }, []); const routes = ([ - } />, - } />, - } />, + } />, + } />, + } />, } />, } /> ] ); - const onboarded = () => gang.chip_name && gang.chip_name.length > 0; + const onboarded = () => selectedGang.chip_name && selectedGang.chip_name.length > 0; const preloaderCircle = (
@@ -72,11 +74,34 @@ const App = (props) => {
); + const navbarLogoWithGang = ( +
+ GKS + + {selectedGang && selectedGang.name && selectedGang.name.length > 0 ? `${selectedGang.name} gang` : '[No name gang]'}arrow_drop_down} + > + {gangs.map(gang => {`${gang.name} gang`})} + +
+ ); + return (
- GKS} alignLinks="right"> + Crib @@ -97,7 +122,7 @@ const App = (props) => {
{ loading && preloaderCircle } - { !loading && !onboarded() && } + { !loading && !onboarded() && } { !loading && onboarded() && routes }
diff --git a/client/src/gangOnboarding/ChipSelection.js b/client/src/gangOnboarding/GangOnboarding.js similarity index 68% rename from client/src/gangOnboarding/ChipSelection.js rename to client/src/gangOnboarding/GangOnboarding.js index af7ee9a..5f5dcb3 100644 --- a/client/src/gangOnboarding/ChipSelection.js +++ b/client/src/gangOnboarding/GangOnboarding.js @@ -1,11 +1,14 @@ import React, { useState, useEffect } from 'react'; import axios from "axios"; import { errorToast } from "../common/errorHelpers"; -import {Button, Select, TextInput} from "react-materialize"; +import {Button, Select} from "react-materialize"; -const ChipSelection = (props) => { +const GangOnboarding = (props) => { const [chips, setChips] = useState([]); const [selectedChip, setSelectedChip] = useState('1'); + const [gangName, setGangName] = useState(''); + + const gang = props.gang; useEffect(() => { (async() => { @@ -25,22 +28,23 @@ const ChipSelection = (props) => { const chipsToOptions = chips.map( (chip, index) => ); const disableSubmit = () => { - return !(parseInt(selectedChip) > 0); + return parseInt(selectedChip) === 0 || gangName.length === 0 ; } const handleSubmit = async () => { const chipData = chips.find(chip => chip.id === parseInt(selectedChip)); if (chipData){ - const gang = { + const updatedGang = { chip_name: chipData.name, chip_code: chipData.code, chip_symbol: chipData.symbol, chip_prefixed: chipData.prefixed, - chip_scale: chipData.scale + chip_scale: chipData.scale, + name: gangName } try{ - const response = await axios.put('/api/gangs/0', { 'gang': gang }); + const response = await axios.put(`/api/gangs/${gang.id}`, { 'gang': updatedGang }); if (response.status === 200 && response.data && response.data.onboarded) { window.location.reload(); }else{ @@ -56,6 +60,12 @@ const ChipSelection = (props) => { return (
+ +
+ setGangName(e.target.value)} /> + +
+ @@ -67,4 +77,4 @@ const ChipSelection = (props) => { ) } -export default ChipSelection; \ No newline at end of file +export default GangOnboarding; \ No newline at end of file diff --git a/client/src/homies/Homies.js b/client/src/homies/Homies.js index 3e7ffdd..a68f8d0 100644 --- a/client/src/homies/Homies.js +++ b/client/src/homies/Homies.js @@ -62,7 +62,7 @@ const Homies = (props) => { return (
- +
    { homiesData } diff --git a/client/src/homies/NewHomieForm.js b/client/src/homies/NewHomieForm.js index 04fcec3..cf30f2b 100644 --- a/client/src/homies/NewHomieForm.js +++ b/client/src/homies/NewHomieForm.js @@ -10,6 +10,8 @@ const NewHomieForm = (props) => { const [homieImportance, setHomieImportance] = useState(""); const [busy, setBusy] = useState(false); + const gang = props.gang; + const disableAddButton = () => { return homieName.length === 0 || homieImportance === "" || @@ -33,7 +35,8 @@ const NewHomieForm = (props) => { homie: { name: homieName, about: aboutHomie, - importance: parseInt(homieImportance) + importance: parseInt(homieImportance), + gang_id: gang.id } } @@ -57,7 +60,7 @@ const NewHomieForm = (props) => { return (
    - Introduce new homie to the Hood}> + {`Introduce new homie to the ${gang.name} gang`}}>
    setHomieName(e.target.value)} /> From 8832ba071bc741a2ba80ba3928b4906f50835df0 Mon Sep 17 00:00:00 2001 From: Bilal Date: Wed, 7 Oct 2020 22:47:19 +0300 Subject: [PATCH 3/7] add homie to the gang when homie is created --- app/controllers/gangs_controller.rb | 9 ++++++++- app/controllers/homies_controller.rb | 3 ++- app/models/gang.rb | 2 +- app/models/homie.rb | 2 ++ config/routes.rb | 2 +- db/migrate/20201007182916_add_name_to_gangs.rb | 5 +++++ .../20201007183139_add_gang_relation_to_homies.rb | 5 +++++ ...3411_add_initial_gang_and_connect_to_homies.rb | 15 +++++++++++++++ db/schema.rb | 5 ++++- 9 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20201007182916_add_name_to_gangs.rb create mode 100644 db/migrate/20201007183139_add_gang_relation_to_homies.rb create mode 100644 db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb diff --git a/app/controllers/gangs_controller.rb b/app/controllers/gangs_controller.rb index 958b243..82204a4 100644 --- a/app/controllers/gangs_controller.rb +++ b/app/controllers/gangs_controller.rb @@ -1,4 +1,10 @@ class GangsController < ApplicationController + def index + json_response Gang.all + rescue StandardError + error_response :bad_request + end + def show if Gang.count.zero? Gang.create.save @@ -19,7 +25,8 @@ class GangsController < ApplicationController private def gang_params - params.require(:gang).permit :chip_name, + params.require(:gang).permit :name, + :chip_name, :chip_code, :chip_symbol, :chip_scale, diff --git a/app/controllers/homies_controller.rb b/app/controllers/homies_controller.rb index 4d2da8a..66ad232 100644 --- a/app/controllers/homies_controller.rb +++ b/app/controllers/homies_controller.rb @@ -46,7 +46,8 @@ class HomiesController < ApplicationController params.require(:homie).permit( :name, :importance, - :about + :about, + :gang_id ) end end diff --git a/app/models/gang.rb b/app/models/gang.rb index e2d3d62..00db4a6 100644 --- a/app/models/gang.rb +++ b/app/models/gang.rb @@ -1,3 +1,3 @@ class Gang < ApplicationRecord - + has_many :homies end \ No newline at end of file diff --git a/app/models/homie.rb b/app/models/homie.rb index 65e5271..c4e8e1b 100644 --- a/app/models/homie.rb +++ b/app/models/homie.rb @@ -2,6 +2,8 @@ class Homie < ApplicationRecord has_many :money_moves has_many :work + belongs_to :gang + def self.info(importance) cash_totals = Homie.all.joins(:money_moves).group(:id).order(:id).sum(:amount) work_totals = Homie.all.joins(:work).group(:id).order(:id).sum(:amount) diff --git a/config/routes.rb b/config/routes.rb index fa4ec00..ea639b5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ Rails.application.routes.draw do constraints format: :json do scope :api do - resources :gangs, only: [:show, :update] + resources :gangs, only: [:index, :show, :update] resources :money_moves resources :work resources :chips, only: %i[index create destroy] diff --git a/db/migrate/20201007182916_add_name_to_gangs.rb b/db/migrate/20201007182916_add_name_to_gangs.rb new file mode 100644 index 0000000..26c258e --- /dev/null +++ b/db/migrate/20201007182916_add_name_to_gangs.rb @@ -0,0 +1,5 @@ +class AddNameToGangs < ActiveRecord::Migration[5.2] + def change + add_column :gangs, :name, :text + end +end \ No newline at end of file diff --git a/db/migrate/20201007183139_add_gang_relation_to_homies.rb b/db/migrate/20201007183139_add_gang_relation_to_homies.rb new file mode 100644 index 0000000..b1808a4 --- /dev/null +++ b/db/migrate/20201007183139_add_gang_relation_to_homies.rb @@ -0,0 +1,5 @@ +class AddGangRelationToHomies < ActiveRecord::Migration[5.2] + def change + add_reference :homies, :gang + end +end \ No newline at end of file diff --git a/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb new file mode 100644 index 0000000..5ca4667 --- /dev/null +++ b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb @@ -0,0 +1,15 @@ +class AddInitialGangAndConnectToHomies < ActiveRecord::Migration[5.2] + def up + # execute "INSERT INTO gangs SELECT 'name' WHERE NOT EXISTS (SELECT * FROM gangs)" + if Gang.count.zero? + Gang.create.save + end + gang = Gang.first + + Homie.all.update(gang: gang) + end + + def down + Homie.all.update(gang: nil) + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 28977bc..dc50711 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_10_07_180902) do +ActiveRecord::Schema.define(version: 2020_10_07_213411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -43,6 +43,7 @@ ActiveRecord::Schema.define(version: 2020_10_07_180902) do t.integer "chip_scale" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "name" end create_table "homies", force: :cascade do |t| @@ -51,6 +52,8 @@ ActiveRecord::Schema.define(version: 2020_10_07_180902) do t.text "about" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "gang_id" + t.index ["gang_id"], name: "index_homies_on_gang_id" end create_table "money_moves", force: :cascade do |t| From 51d8a369a96cd291e251a18c0a900e508e8bafbc Mon Sep 17 00:00:00 2001 From: Bilal Date: Thu, 8 Oct 2020 01:06:51 +0300 Subject: [PATCH 4/7] implement adding new gang, show only homies for selected gang --- client/src/App.js | 19 ++++-- client/src/RouteNames.js | 1 + client/src/cash/Cash.js | 4 +- client/src/cash/MakeMoneyMove.js | 5 +- client/src/cash/PutInWork.js | 4 +- client/src/gangs/Gangs.js | 59 ++++++++++++++++ client/src/gangs/NewGangForm.js | 110 ++++++++++++++++++++++++++++++ client/src/homies/Homies.js | 6 +- client/src/homies/NewHomieForm.js | 6 +- 9 files changed, 198 insertions(+), 16 deletions(-) create mode 100644 client/src/gangs/Gangs.js create mode 100644 client/src/gangs/NewGangForm.js diff --git a/client/src/App.js b/client/src/App.js index 8d7bb75..8f50db0 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -10,6 +10,7 @@ import RoutableNavItem from './common/RoutableNavItem'; import axios from 'axios'; import { CRIB, + GANGS, MAKE_MONEY_MOVE, HOMIE_FLOW, HOMIES, @@ -17,6 +18,7 @@ import { } from './RouteNames'; import PutInWork from "./cash/PutInWork"; import GangOnboarding from "./gangOnboarding/GangOnboarding"; +import Gangs from './gangs/Gangs'; import {errorToast} from "./common/errorHelpers"; @@ -45,10 +47,11 @@ const App = (props) => { const routes = ([ } />, - } />, - } />, - } />, - } /> + } />, + } />, + } />, + } />, + } /> ] ); @@ -85,14 +88,14 @@ const App = (props) => { autoTrigger: true, closeOnClick: true, constrainWidth: true, - coverTrigger: true, + coverTrigger: false, hover: false, inDuration: 150, outDuration: 250 }} trigger={{selectedGang && selectedGang.name && selectedGang.name.length > 0 ? `${selectedGang.name} gang` : '[No name gang]'}arrow_drop_down} > - {gangs.map(gang => {`${gang.name} gang`})} + {gangs.map(gang => setSelectedGang(gang)}>{gang.name})}
    ); @@ -106,6 +109,10 @@ const App = (props) => { Crib + + Gangs + + Homies diff --git a/client/src/RouteNames.js b/client/src/RouteNames.js index 446919b..98ccb73 100644 --- a/client/src/RouteNames.js +++ b/client/src/RouteNames.js @@ -3,3 +3,4 @@ export const HOMIES = '/homies'; export const MAKE_MONEY_MOVE = '/make-money-move'; export const PUT_IN_WORK = '/put-in-work'; export const HOMIE_FLOW = '/homie/:homie_id/flow'; +export const GANGS = '/gangs'; diff --git a/client/src/cash/Cash.js b/client/src/cash/Cash.js index 22f53ca..c3848b0 100644 --- a/client/src/cash/Cash.js +++ b/client/src/cash/Cash.js @@ -16,7 +16,7 @@ const Cash = (props) => { useEffect( () => { const getCashForHomies = async () => { try { - const cash = await axios.get(`/api/homies/info`); + const cash = await axios.get(`/api/gangs/${gang.id}/homies/info`); setHomiesCash(cash.data); } catch (e) { console.log("Error fetching", e); @@ -27,7 +27,7 @@ const Cash = (props) => { const settleFlowForHomie = async (id, amountToSettle) => { try { - const response = await axios.post(`/api/homies/${id}/settle`, { amount: amountToSettle }); + const response = await axios.post(`/api/gangs/${gang.id}/homies/${id}/settle`, { amount: amountToSettle }); if (response.status === 200 && response.data) { M.toast({ html: 'Settled' }); setHomiesCash(response.data); diff --git a/client/src/cash/MakeMoneyMove.js b/client/src/cash/MakeMoneyMove.js index 8b8ccd5..6f47c03 100644 --- a/client/src/cash/MakeMoneyMove.js +++ b/client/src/cash/MakeMoneyMove.js @@ -5,7 +5,6 @@ import './Cash.css'; import axios from 'axios'; const MakeMoneyMove = (props) => { - const [selectedFrom, setSelectedFrom] = useState(""); const [selectedTo, setSelectedTo] = useState("-1"); const [homiesCash, setHomiesCash] = useState([]); @@ -13,10 +12,12 @@ const MakeMoneyMove = (props) => { const [moveDescription, setMoveDescription] = useState(""); const [submitInProgress, setSubmitInProgress] = useState(false); + const gang = props.gang; + useEffect(() => { const getCashForHomies = async () => { try { - const cash = await axios.get(`/api/homies/info`); + const cash = await axios.get(`/api/gangs/${gang.id}/homies/info`); setHomiesCash(cash.data); } catch (e) { console.log("Error fetching", e); diff --git a/client/src/cash/PutInWork.js b/client/src/cash/PutInWork.js index 62f9c1b..f864f82 100644 --- a/client/src/cash/PutInWork.js +++ b/client/src/cash/PutInWork.js @@ -12,10 +12,12 @@ const PutInWork = (props) => { const [workDescription, setWorkDescription] = useState(''); const [submitInProgress, setSubmitInProgress] = useState(false); + const gang = props.gang; + useEffect(() => { (async () => { try { - const response = await axios.get('/api/homies'); + const response = await axios.get(`/api/gangs/${gang.id}/homies`); if (response.status === 200 && response.data){ setHomies(response.data); } diff --git a/client/src/gangs/Gangs.js b/client/src/gangs/Gangs.js new file mode 100644 index 0000000..b36fe6d --- /dev/null +++ b/client/src/gangs/Gangs.js @@ -0,0 +1,59 @@ +import React, { useEffect, useState } from 'react'; +import NewGangForm from "./NewGangForm"; +import axios from "axios"; +import {errorToast} from "../common/errorHelpers"; +import YesNoModal from "../common/YesNoModal"; +import {Button} from "react-materialize"; +import M from "materialize-css"; + +const Gangs = (props) => { + const gangs = props.gangs; + const setGangs = props.gangsSetter; + + const deleteGang = async (id) => { + try { + const response = await axios.delete(`/api/gangs/${id}`); + if (response.status === 200 && response.data){ + setGangs(response.data); + M.toast({ html: "See y'a on the other side" }); + }else{ + errorToast(); + } + }catch (e) { + console.log(e); + errorToast(); + } + } + + const gangsData = gangs.map((gang, index) => { + return ( +
  • +
    +
    +
    +
    { gang.name }
    +
    { `${gang.about || '[no about]'} • ${gang.chip_name} (${gang.chip_code})`}
    +
    + + deleteGang(gang.id)} + triggerNode={
    +
    +
  • + ) + }); + + return ( +
    + + +
      + { gangsData } +
    +
    + ) +} + +export default Gangs; \ No newline at end of file diff --git a/client/src/gangs/NewGangForm.js b/client/src/gangs/NewGangForm.js new file mode 100644 index 0000000..23baf23 --- /dev/null +++ b/client/src/gangs/NewGangForm.js @@ -0,0 +1,110 @@ +import React, { useEffect, useState } from 'react'; +import { Button, Collapsible, CollapsibleItem, Select, TextInput } from 'react-materialize'; +import axios from 'axios'; +import { errorToast } from "../common/errorHelpers"; +import M from 'materialize-css'; + +const NewGangForm = (props) => { + const [gangName, setGangName] = useState(""); + const [aboutGang, setAboutGang] = useState(""); + const [chips, setChips] = useState([]); + const [selectedChip, setSelectedChip] = useState('1'); + const [busy, setBusy] = useState(false); + + useEffect(() => { + (async() => { + try { + const response = await axios.get(`/api/chips`); + if (response.status === 200 && response.data){ + setChips(response.data); + }else{ + errorToast(); + } + } catch (e) { + errorToast(); + } + })(); + }, []); + + const chipsToOptions = chips.map( (chip, index) => ); + + const disableAddButton = () => { + return gangName.length === 0 || busy; + } + + const clearForm = () => { + setGangName(""); + setAboutGang(""); + + const collapsible = document.getElementById('new-gang-form-container'); + const collapsibleInstance = M.Collapsible.getInstance(collapsible); + + collapsibleInstance.close(0); + } + + const addNewGang = async () => { + const chipData = chips.find(chip => chip.id === parseInt(selectedChip)); + if (chipData) { + setBusy(true); + const newGang = { + chip_name: chipData.name, + chip_code: chipData.code, + chip_symbol: chipData.symbol, + chip_prefixed: chipData.prefixed, + chip_scale: chipData.scale, + name: gangName, + about: aboutGang + } + + try { + const response = await axios.post('/api/gangs', {gang: newGang}); + if (response.status === 200 && response.data) { + props.newGangsSetter(response.data); + M.toast({html: 'Welcome to the Hood'}); + clearForm(); + } else { + errorToast(); + } + } catch (e) { + console.log(e.message); + errorToast(); + } + + setBusy(false); + }else{ + errorToast(); + } + } + + return ( +
    + + {`Introduce new gang to the Hood`}}> +
    + setGangName(e.target.value)} /> + + +
    + + setAboutGang(e.target.value)} + /> + + + +
    + + + +
    +
    +
    + ) +} + +export default NewGangForm; \ No newline at end of file diff --git a/client/src/homies/Homies.js b/client/src/homies/Homies.js index a68f8d0..646cbcc 100644 --- a/client/src/homies/Homies.js +++ b/client/src/homies/Homies.js @@ -10,10 +10,12 @@ import YesNoModal from "../common/YesNoModal"; const Homies = (props) => { const [homies, setHomies] = useState([]); + const gang = props.gang; + useEffect(() => { (async() => { try { - const response = await axios.get(`/api/homies`); + const response = await axios.get(`/api/gangs/${gang.id}/homies`); if (response.status === 200 && response.data){ setHomies(response.data); }else{ @@ -27,7 +29,7 @@ const Homies = (props) => { const deleteHomie = async (id) => { try { - const response = await axios.delete(`/api/homies/${id}`); + const response = await axios.delete(`/api/gangs/${gang.id}/homies/${id}`); if (response.status === 200 && response.data){ setHomies(response.data); M.toast({ html: "See y'a on the other side Homie" }); diff --git a/client/src/homies/NewHomieForm.js b/client/src/homies/NewHomieForm.js index cf30f2b..187265e 100644 --- a/client/src/homies/NewHomieForm.js +++ b/client/src/homies/NewHomieForm.js @@ -41,10 +41,10 @@ const NewHomieForm = (props) => { } try{ - const response = await axios.post('/api/homies', newHomie); + const response = await axios.post(`/api/gangs/${gang.id}/homies`, newHomie); if (response.status === 200 && response.data) { props.newHomiesSetter(response.data); - M.toast({ html: 'Welcome to the hood' }); + M.toast({ html: 'Welcome to the Gang' }); clearForm(); }else{ errorToast(); @@ -86,7 +86,7 @@ const NewHomieForm = (props) => {
    - +
    From e65f352108c4794dd7af11770625528f81750078 Mon Sep 17 00:00:00 2001 From: Bilal Date: Thu, 8 Oct 2020 01:13:57 +0300 Subject: [PATCH 5/7] move homies under gang --- app/controllers/gangs_controller.rb | 13 +++++++++---- app/controllers/homies_controller.rb | 7 +++++-- app/models/homie.rb | 6 ++++-- config/routes.rb | 19 ++++++++++--------- .../20201007182916_add_name_to_gangs.rb | 1 + db/schema.rb | 1 + 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/app/controllers/gangs_controller.rb b/app/controllers/gangs_controller.rb index 82204a4..dd70326 100644 --- a/app/controllers/gangs_controller.rb +++ b/app/controllers/gangs_controller.rb @@ -5,12 +5,16 @@ class GangsController < ApplicationController error_response :bad_request end - def show - if Gang.count.zero? - Gang.create.save + def create + gang = Gang.create(gang_params) + if gang.save + json_response Gang.all + else + error_response :bad_request end - json_response Gang.first + rescue StandardError + error_response :bad_request end def update @@ -26,6 +30,7 @@ class GangsController < ApplicationController def gang_params params.require(:gang).permit :name, + :about, :chip_name, :chip_code, :chip_symbol, diff --git a/app/controllers/homies_controller.rb b/app/controllers/homies_controller.rb index 66ad232..ff64f42 100644 --- a/app/controllers/homies_controller.rb +++ b/app/controllers/homies_controller.rb @@ -1,6 +1,8 @@ class HomiesController < ApplicationController def index - json_response(Homie.all.order(importance: :desc, name: :asc)) + homies = Homie.where(gang: params[:gang_id]).order(importance: :desc, name: :asc) + # json_response(Homie.all.order(importance: :desc, name: :asc)) + json_response homies end def create @@ -23,7 +25,8 @@ class HomiesController < ApplicationController def info importance = params[:importance].present? ? params[:importance].to_i : -1 - json_response(Homie.info(importance)) + gang = params[:gang_id] + json_response(Homie.info(importance, gang)) end def settle diff --git a/app/models/homie.rb b/app/models/homie.rb index c4e8e1b..9ad4538 100644 --- a/app/models/homie.rb +++ b/app/models/homie.rb @@ -4,11 +4,13 @@ class Homie < ApplicationRecord belongs_to :gang - def self.info(importance) + def self.info(importance, gang) + # TODO: This can be improved + cash_totals = Homie.all.joins(:money_moves).group(:id).order(:id).sum(:amount) work_totals = Homie.all.joins(:work).group(:id).order(:id).sum(:amount) - Homie.where(["importance > ?", importance]).map do |homie| + Homie.where(['importance > ? and gang_id = ?', importance, gang]).map do |homie| cash_total = cash_totals.fetch(homie.id, 0) work_total = work_totals.fetch(homie.id, 0) { homie: homie, amount: cash_total, work: work_total } diff --git a/config/routes.rb b/config/routes.rb index ea639b5..06d8614 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,19 +1,20 @@ Rails.application.routes.draw do constraints format: :json do scope :api do - resources :gangs, only: [:index, :show, :update] + resources :gangs, only: [:index, :create, :update] do + resources :homies, param: :homie_id do + collection do + get 'info' + end + member do + post 'settle' + end + end + end resources :money_moves resources :work resources :chips, only: %i[index create destroy] resources :chip_values, only: %i[create update destroy] - resources :homies, param: :homie_id do - collection do - get 'info' - end - member do - post 'settle' - end - end end end diff --git a/db/migrate/20201007182916_add_name_to_gangs.rb b/db/migrate/20201007182916_add_name_to_gangs.rb index 26c258e..379adb5 100644 --- a/db/migrate/20201007182916_add_name_to_gangs.rb +++ b/db/migrate/20201007182916_add_name_to_gangs.rb @@ -1,5 +1,6 @@ class AddNameToGangs < ActiveRecord::Migration[5.2] def change add_column :gangs, :name, :text + add_column :gangs, :about, :text end end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index dc50711..80897d6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -44,6 +44,7 @@ ActiveRecord::Schema.define(version: 2020_10_07_213411) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.text "name" + t.text "about" end create_table "homies", force: :cascade do |t| From 8cb44e4b16add87b07b48471272a3180fb75506b Mon Sep 17 00:00:00 2001 From: Bilal Date: Thu, 8 Oct 2020 01:18:32 +0300 Subject: [PATCH 6/7] set default gang name --- .../20201007213411_add_initial_gang_and_connect_to_homies.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb index 5ca4667..aea3385 100644 --- a/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb +++ b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb @@ -2,7 +2,7 @@ class AddInitialGangAndConnectToHomies < ActiveRecord::Migration[5.2] def up # execute "INSERT INTO gangs SELECT 'name' WHERE NOT EXISTS (SELECT * FROM gangs)" if Gang.count.zero? - Gang.create.save + Gang.create(name: 'Default').save end gang = Gang.first From 9fc4bb6ddbf75fe470dfabf1aa619ba076ed6987 Mon Sep 17 00:00:00 2001 From: Bilal Date: Thu, 8 Oct 2020 01:28:03 +0300 Subject: [PATCH 7/7] update gang name if already exists --- .../20201007213411_add_initial_gang_and_connect_to_homies.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb index aea3385..93e25aa 100644 --- a/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb +++ b/db/migrate/20201007213411_add_initial_gang_and_connect_to_homies.rb @@ -1,8 +1,9 @@ class AddInitialGangAndConnectToHomies < ActiveRecord::Migration[5.2] def up - # execute "INSERT INTO gangs SELECT 'name' WHERE NOT EXISTS (SELECT * FROM gangs)" if Gang.count.zero? Gang.create(name: 'Default').save + elsif Gang.count == 1 + Gang.update name: 'Default' end gang = Gang.first