diff --git a/app/controllers/chips_controller.rb b/app/controllers/chips_controller.rb index b19e27a..c1c6add 100644 --- a/app/controllers/chips_controller.rb +++ b/app/controllers/chips_controller.rb @@ -1,6 +1,32 @@ class ChipsController < ApplicationController def index - json_response Chip.where(enabled: true).order(:name).to_json(include: :base_chip_values) + all_chips = [ + { + id: 1, + name: 'US Dollar', + symbol: '$', + code: 'USD', + scale: 2, + prefixed: true + }, + { + id: 2, + name: 'Bosnian Convertible Mark', + symbol: 'KM', + code: 'BAM', + scale: 2, + prefixed: false + }, + { + id: 3, + name: 'Euro', + symbol: '€', + code: 'EUR', + scale: 3, + prefixed: false + } + ] + json_response all_chips end def create diff --git a/app/controllers/homies_controller.rb b/app/controllers/homies_controller.rb index f93d5e9..4d2da8a 100644 --- a/app/controllers/homies_controller.rb +++ b/app/controllers/homies_controller.rb @@ -46,8 +46,7 @@ class HomiesController < ApplicationController params.require(:homie).permit( :name, :importance, - :about, - :chip_id + :about ) end end diff --git a/app/controllers/original_gangstas_controller.rb b/app/controllers/original_gangstas_controller.rb new file mode 100644 index 0000000..2d5debe --- /dev/null +++ b/app/controllers/original_gangstas_controller.rb @@ -0,0 +1,28 @@ +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/homie.rb b/app/models/homie.rb index be5ef9d..65e5271 100644 --- a/app/models/homie.rb +++ b/app/models/homie.rb @@ -1,7 +1,6 @@ class Homie < ApplicationRecord has_many :money_moves has_many :work - belongs_to :chip def self.info(importance) cash_totals = Homie.all.joins(:money_moves).group(:id).order(:id).sum(:amount) diff --git a/app/models/original_gangsta.rb b/app/models/original_gangsta.rb new file mode 100644 index 0000000..a579514 --- /dev/null +++ b/app/models/original_gangsta.rb @@ -0,0 +1,3 @@ +class OriginalGangsta < ApplicationRecord + +end \ No newline at end of file diff --git a/client/src/App.css b/client/src/App.css index 4a6d56e..d5bdbce 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -48,4 +48,10 @@ .required:before { color: red; content: "* "; +} + +.preloader-circle { + position: absolute; + height: 90%; + margin-left: 40%; } \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index e831832..2c8d82b 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,24 +1,78 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import './App.css'; import { Navbar } from 'react-materialize'; import MakeMoneyMove from './cash/MakeMoneyMove'; import Flow from "./homies/Flow"; import Cash from './cash/Cash'; -import Chips from './chips/Chips'; import Homies from './homies/Homies'; import { BrowserRouter as Router, Route } from "react-router-dom"; import RoutableNavItem from './common/RoutableNavItem'; +import axios from 'axios'; import { CRIB, - CHIPS, MAKE_MONEY_MOVE, HOMIE_FLOW, - HOMIES, PUT_IN_WORK + HOMIES, + PUT_IN_WORK } from './RouteNames'; import PutInWork from "./cash/PutInWork"; +import ChipSelection from "./originalGangstaOnboarding/ChipSelection"; +import {errorToast} from "./common/errorHelpers"; + + +const App = (props) => { + const [loading, setLoading] = useState(true); + const [originalGangsta, setOriginalGangsta] = useState({}); + + useEffect(() => { + (async() => { + try { + setLoading(true); + const response = await axios.get(`/api/original_gangstas/0`); + if (response.status === 200 && response.data){ + setOriginalGangsta(response.data); + }else{ + errorToast(); + } + } catch (e) { + errorToast(); + } + setLoading(false); + })(); + }, []); + + const routes = ([ + } />, + } />, + } />, + } />, + } /> + ] + ); + + const onboarded = () => originalGangsta.chip_name && originalGangsta.chip_name.length > 0; + + const preloaderCircle = ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ); -function App() { return (
@@ -31,10 +85,6 @@ function App() { Homies - - Chips - - Make Money Move @@ -46,12 +96,9 @@ function App() {
- - - - - - + { loading && preloaderCircle } + { !loading && !onboarded() && } + { !loading && onboarded() && routes }
); diff --git a/client/src/RouteNames.js b/client/src/RouteNames.js index ae706c3..446919b 100644 --- a/client/src/RouteNames.js +++ b/client/src/RouteNames.js @@ -1,6 +1,5 @@ export const CRIB = '/'; export const HOMIES = '/homies'; -export const CHIPS = '/chips'; export const MAKE_MONEY_MOVE = '/make-money-move'; export const PUT_IN_WORK = '/put-in-work'; export const HOMIE_FLOW = '/homie/:homie_id/flow'; diff --git a/client/src/cash/Cash.js b/client/src/cash/Cash.js index a59ccd3..331591e 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 [importance, setImportance] = useState(10); + const originalGangsta = props.originalGangsta; useEffect( () => { const getCashForHomies = async () => { @@ -49,7 +49,7 @@ const Cash = (props) => { { formatTime(homieLine.work) } - { formatMoney(homieLine.amount) } + { formatMoney(homieLine.amount, originalGangsta) } [ diff --git a/client/src/common/formatting.js b/client/src/common/formatting.js index 1f64e6c..56fdbc7 100644 --- a/client/src/common/formatting.js +++ b/client/src/common/formatting.js @@ -1,6 +1,10 @@ -const formatMoney = (amount) => { - const formatted = Number.parseFloat(amount).toFixed(2); - return `${formatted} KM`; +const formatMoney = (amount, originalGangsta) => { + const decimalPlaces = parseInt(originalGangsta['chip_scale']); + const symbol = originalGangsta['chip_symbol']; + const prefixed = originalGangsta['chip_prefixed']; + + const formatted = Number.parseFloat(amount).toFixed(decimalPlaces); + return prefixed ? `${symbol} ${formatted}` : `${formatted} ${symbol}`; } const formatTime = (amount) => { diff --git a/client/src/homies/CashFlow.js b/client/src/homies/CashFlow.js index b09f62c..4694011 100644 --- a/client/src/homies/CashFlow.js +++ b/client/src/homies/CashFlow.js @@ -7,6 +7,7 @@ import {errorToast} from "../common/errorHelpers"; const CashFlow = (props) => { const { homie_id } = useParams(); + const originalGangsta = props.originalGangsta; const [cashFlow, setCashFlow] = useState([]); @@ -34,7 +35,7 @@ const CashFlow = (props) => {
{ dateBlock(singleFlowData['created_at']) }
-
0 ? 'amount-green' : ''}`}>{ formatMoney(singleFlowData.amount) }
+
0 ? 'amount-green' : ''}`}>{ formatMoney(singleFlowData.amount, originalGangsta) }
@@ -57,7 +58,7 @@ const CashFlow = (props) => { {`${totalCount} Records`}{` • ${fromDate} - ${toDate}`}
- Total cash flow: {formatMoney(totalFlow)} + Total cash flow: {formatMoney(totalFlow, originalGangsta)}
diff --git a/client/src/homies/Flow.js b/client/src/homies/Flow.js index 87a82d9..78eb8f5 100644 --- a/client/src/homies/Flow.js +++ b/client/src/homies/Flow.js @@ -7,6 +7,7 @@ import WorkFlow from "./WorkFlow"; const Flow = (props) => { const [flowType, setFlowType] = useState('cash'); + const originalGangsta = props.originalGangsta; return (
@@ -18,7 +19,7 @@ const Flow = (props) => { />
- { flowType === 'cash' && } + { flowType === 'cash' && } { flowType === 'work' && } diff --git a/client/src/homies/NewHomieForm.js b/client/src/homies/NewHomieForm.js index 2e9d9f9..04fcec3 100644 --- a/client/src/homies/NewHomieForm.js +++ b/client/src/homies/NewHomieForm.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { Button, Collapsible, CollapsibleItem, Select, TextInput } from 'react-materialize'; import axios from 'axios'; import { errorToast } from "../common/errorHelpers"; @@ -8,31 +8,11 @@ const NewHomieForm = (props) => { const [homieName, setHomieName] = useState(""); const [aboutHomie, setAboutHomie] = useState(""); const [homieImportance, setHomieImportance] = useState(""); - const [homieDefaultChip, setHomieDefaultChip] = useState(""); - const [chips, setChips] = useState([]); 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 chipOptions = chips.map((chip, index) => ); - const disableAddButton = () => { return homieName.length === 0 || homieImportance === "" || - homieDefaultChip === "" || busy; } @@ -40,7 +20,6 @@ const NewHomieForm = (props) => { setHomieName(""); setAboutHomie(""); setHomieImportance(""); - setHomieDefaultChip(""); const collapsible = document.getElementById('new-homie-form-container'); const collapsibleInstance = M.Collapsible.getInstance(collapsible); @@ -54,8 +33,7 @@ const NewHomieForm = (props) => { homie: { name: homieName, about: aboutHomie, - importance: parseInt(homieImportance), - chip_id: parseInt(homieDefaultChip) + importance: parseInt(homieImportance) } } @@ -103,12 +81,6 @@ const NewHomieForm = (props) => { - - -
diff --git a/client/src/originalGangstaOnboarding/ChipSelection.js b/client/src/originalGangstaOnboarding/ChipSelection.js new file mode 100644 index 0000000..1bd167c --- /dev/null +++ b/client/src/originalGangstaOnboarding/ChipSelection.js @@ -0,0 +1,70 @@ +import React, { useState, useEffect } from 'react'; +import axios from "axios"; +import { errorToast } from "../common/errorHelpers"; +import {Button, Select, TextInput} from "react-materialize"; + +const ChipSelection = (props) => { + const [chips, setChips] = useState([]); + const [selectedChip, setSelectedChip] = useState('1'); + + 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 disableSubmit = () => { + return !(parseInt(selectedChip) > 0); + } + + const handleSubmit = async () => { + const chipData = chips.find(chip => chip.id === parseInt(selectedChip)); + if (chipData){ + const originalGangsta = { + chip_name: chipData.name, + chip_code: chipData.code, + chip_symbol: chipData.symbol, + chip_prefixed: chipData.prefixed, + chip_scale: chipData.scale + } + + try{ + const response = await axios.put('/api/original_gangstas/0', { 'original_gangsta': originalGangsta }); + if (response.status === 200 && response.data && response.data.onboarded) { + window.location.reload(); + }else{ + errorToast(); + } + }catch (e) { + errorToast(); + } + }else{ + errorToast(); + } + } + + return ( +
+ + + +
+ ) +} + +export default ChipSelection; \ No newline at end of file diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index ab4f265..9f8e25d 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -17,4 +17,5 @@ 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 dbd5365..6ebc143 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,7 @@ Rails.application.routes.draw do constraints format: :json do scope :api do + resources :original_gangstas, only: [:show, :update] resources :money_moves resources :work resources :chips, only: %i[index create destroy] diff --git a/db/migrate/20201006120708_remove_default_chip_ref_from_homies.rb b/db/migrate/20201006120708_remove_default_chip_ref_from_homies.rb new file mode 100644 index 0000000..bfa8b96 --- /dev/null +++ b/db/migrate/20201006120708_remove_default_chip_ref_from_homies.rb @@ -0,0 +1,5 @@ +class RemoveDefaultChipRefFromHomies < ActiveRecord::Migration[5.2] + def change + remove_reference :homies, :chip + end +end diff --git a/db/migrate/20201006120951_create_original_gangstas.rb b/db/migrate/20201006120951_create_original_gangstas.rb new file mode 100644 index 0000000..12f3016 --- /dev/null +++ b/db/migrate/20201006120951_create_original_gangstas.rb @@ -0,0 +1,13 @@ +class CreateOriginalGangstas < ActiveRecord::Migration[5.2] + def change + create_table :original_gangstas do |t| + t.text :chip_name + t.text :chip_code + t.text :chip_symbol + t.boolean :chip_prefixed + t.integer :chip_scale + + t.timestamps + end + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 902c3f0..e1a270a 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_103421) do +ActiveRecord::Schema.define(version: 2020_10_06_120951) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -41,8 +41,6 @@ ActiveRecord::Schema.define(version: 2020_10_06_103421) do t.text "about" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.bigint "chip_id" - t.index ["chip_id"], name: "index_homies_on_chip_id" end create_table "money_moves", force: :cascade do |t| @@ -53,6 +51,16 @@ ActiveRecord::Schema.define(version: 2020_10_06_103421) 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"