├── .watchmanconfig ├── .eslintignore ├── .gitattributes ├── app.json ├── android ├── .settings │ └── org.eclipse.buildship.core.prefs ├── app │ ├── debug.keystore │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── drawable │ │ │ │ │ ├── icon.png │ │ │ │ │ └── bootsplash.xml │ │ │ │ ├── drawable-hdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-ldpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-mdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ │ └── icon.png │ │ │ │ ├── drawable-xxhdpi │ │ │ │ │ └── icon.png │ │ │ │ └── drawable-xxxhdpi │ │ │ │ │ └── icon.png │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── cabenomeubolso │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ └── debug │ │ │ └── AndroidManifest.xml │ ├── .classpath │ ├── proguard-rules.pro │ ├── .project │ ├── build_defs.bzl │ ├── _BUCK │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle ├── .project ├── gradle.properties ├── build.gradle ├── gradlew.bat └── gradlew ├── src ├── pages │ ├── CabeSave │ │ ├── components │ │ │ ├── index.ts │ │ │ └── FloatingBottomContainer │ │ │ │ ├── styles.ts │ │ │ │ └── index.tsx │ │ ├── CabeName │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ ├── CabeValue │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ ├── CabeItemsList │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ ├── CabeSaveContext.tsx │ │ └── index.tsx │ ├── Main │ │ └── index.tsx │ ├── CabeProcess │ │ ├── CabeItemQuantity │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ ├── CabeItemValue │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ ├── CabeItems │ │ │ ├── styles.ts │ │ │ └── index.tsx │ │ └── index.tsx │ ├── Intro │ │ ├── styles.ts │ │ └── index.tsx │ ├── FinalizedCabeView │ │ ├── styles.ts │ │ └── index.tsx │ └── CabesList │ │ ├── styles.ts │ │ └── index.tsx ├── typings │ ├── console.d.ts │ └── redux.d.ts ├── store │ ├── modules │ │ ├── rootSaga.ts │ │ ├── meta │ │ │ ├── actions.ts │ │ │ └── reducer.ts │ │ ├── rootReducer.ts │ │ └── cabes │ │ │ ├── reducer.ts │ │ │ ├── actions.ts │ │ │ └── sagas.ts │ ├── createStore.ts │ ├── persistReducers.ts │ └── index.ts ├── styles │ └── colors.ts ├── models │ ├── CabeItem.ts │ └── Cabe.ts ├── components │ ├── Header │ │ ├── styles.ts │ │ └── index.tsx │ ├── index.ts │ ├── ShimmerLoading │ │ ├── index.tsx │ │ └── styles.ts │ ├── NumericKeyboard │ │ ├── styles.ts │ │ └── index.tsx │ ├── Button │ │ └── index.tsx │ └── CabeItemInput │ │ └── index.tsx ├── services │ ├── bd │ │ ├── schemas │ │ │ ├── CabeItemSchema.ts │ │ │ └── CabeSchema.ts │ │ └── index.ts │ └── NavigationService.ts ├── config │ └── ReactotronConfig.ts ├── routes.tsx └── index.tsx ├── .prettierrc.js ├── ios ├── cabenomeubolso │ ├── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.h │ ├── main.m │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.xib ├── cabenomeubolso.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── cabenomeubolsoTests │ ├── Info.plist │ └── cabenomeubolsoTests.m ├── cabenomeubolso-tvOSTests │ └── Info.plist ├── cabenomeubolso-tvOS │ └── Info.plist ├── Podfile ├── cabenomeubolso.xcodeproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── cabenomeubolso.xcscheme │ │ └── cabenomeubolso-tvOS.xcscheme └── Podfile.lock ├── jest.config.js ├── .buckconfig ├── .editorconfig ├── index.js ├── __tests__ └── App-test.tsx ├── metro.config.js ├── privacy.md ├── .gitignore ├── babel.config.js ├── README.md ├── .eslintrc.js ├── package.json └── tsconfig.json /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.d.ts -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cabenomeubolso", 3 | "displayName": "cabenomeubolso" 4 | } -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /src/pages/CabeSave/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FloatingBottomContainer } from './FloatingBottomContainer'; 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | trailingComma: 'es5', 4 | tabWidth: 2, 5 | printWidth: 80, 6 | }; 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Cabe no Meu Bolso 3 | 4 | -------------------------------------------------------------------------------- /ios/cabenomeubolso/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable/icon.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 4 | }; 5 | -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/italomlp/cabenomeubolso/HEAD/android/app/src/main/res/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #fff 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = false 8 | insert_final_newline = false -------------------------------------------------------------------------------- /src/typings/console.d.ts: -------------------------------------------------------------------------------- 1 | import Reactotron from 'reactotron-react-native'; 2 | 3 | declare global { 4 | interface Console { 5 | tron: Reactotron; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/store/modules/rootSaga.ts: -------------------------------------------------------------------------------- 1 | import { all } from 'redux-saga/effects'; 2 | 3 | import cabes from './cabes/sagas'; 4 | 5 | export default function* rootSaga() { 6 | return yield all([cabes]); 7 | } 8 | -------------------------------------------------------------------------------- /src/typings/redux.d.ts: -------------------------------------------------------------------------------- 1 | import { Action as DefaultAction } from 'redux'; 2 | 3 | declare module 'redux' { 4 | export interface Action extends DefaultAction { 5 | payload?: P; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/styles/colors.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | c100: '#2088D0', 3 | c200: '#FFA348', 4 | c300: '#D4328C', 5 | c400: '#4B20AF', 6 | c500: '#5CE7AD', 7 | 8 | n100: '#fff', 9 | n900: '#000', 10 | }; 11 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'cabenomeubolso' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './src'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /src/models/CabeItem.ts: -------------------------------------------------------------------------------- 1 | export interface CanonCabeItem { 2 | id: string; 3 | quantity: number; 4 | name: string; 5 | } 6 | 7 | export interface CabeItem extends CanonCabeItem { 8 | value: number; 9 | done: boolean; 10 | } 11 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/store/modules/meta/actions.ts: -------------------------------------------------------------------------------- 1 | const PREFIX = '@meta'; 2 | 3 | export const TYPES = { 4 | markIntroAsViewed: `${PREFIX}/MARK_INTRO_AS_VIEWED`, 5 | }; 6 | 7 | export function markIntroAsViewed() { 8 | return { 9 | type: TYPES.markIntroAsViewed, 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Header/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | 3 | import colors from 'styles/colors'; 4 | 5 | export const HeaderTitleContainer = styled.Text.attrs({ 6 | numberOfLines: 1, 7 | })` 8 | font-size: 20px; 9 | font-weight: bold; 10 | color: ${colors.n100}; 11 | `; 12 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Header } from './Header'; 2 | export { default as Button } from './Button'; 3 | export { default as NumericKeyboard } from './NumericKeyboard'; 4 | export { default as ShimmerLoading } from './ShimmerLoading'; 5 | export { default as CabeItemInput } from './CabeItemInput'; 6 | -------------------------------------------------------------------------------- /ios/cabenomeubolso.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/cabenomeubolso.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/models/Cabe.ts: -------------------------------------------------------------------------------- 1 | import { CabeItem } from './CabeItem'; 2 | 3 | export interface CanonCabe { 4 | name: string; 5 | id: string; 6 | value: number; 7 | items: CabeItem[]; 8 | } 9 | 10 | export interface Cabe extends CanonCabe { 11 | createdAt: Date; 12 | finalized: boolean; 13 | finalizedAt?: Date; 14 | } 15 | -------------------------------------------------------------------------------- /__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | // Note: test renderer must be required after react-native. 8 | import renderer from 'react-test-renderer'; 9 | 10 | import App from '../src'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/bootsplash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/pages/CabeSave/components/FloatingBottomContainer/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | 3 | export const Container = styled.KeyboardAvoidingView.attrs({ 4 | contentContainerStyle: { flex: 1 }, 5 | })` 6 | position: absolute; 7 | width: 100%; 8 | padding-bottom: 10px; 9 | bottom: 0; 10 | background-color: #fff; 11 | `; 12 | -------------------------------------------------------------------------------- /android/app/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /src/store/createStore.ts: -------------------------------------------------------------------------------- 1 | import { createStore, compose, applyMiddleware } from 'redux'; 2 | 3 | export default (reducers: any, middlewares: any) => { 4 | const composer = 5 | process.env.NODE_ENV === 'development' 6 | ? compose(console.tron.createEnhancer(), applyMiddleware(...middlewares)) 7 | : compose(applyMiddleware(...middlewares)); 8 | 9 | return createStore(reducers, composer); 10 | }; 11 | -------------------------------------------------------------------------------- /src/store/modules/rootReducer.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | 3 | import cabes, { State as CabesState } from './cabes/reducer'; 4 | import meta, { State as MetaState } from './meta/reducer'; 5 | 6 | const reducers = combineReducers({ 7 | cabes, 8 | meta, 9 | }); 10 | 11 | export type RootStore = { 12 | cabes: CabesState; 13 | meta: MetaState; 14 | }; 15 | 16 | export default reducers; 17 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/store/persistReducers.ts: -------------------------------------------------------------------------------- 1 | import { persistReducer } from 'redux-persist'; 2 | import { Reducer } from 'redux'; 3 | import AsyncStorage from '@react-native-community/async-storage'; 4 | 5 | export default (reducers: Reducer) => { 6 | const persistedReducer = persistReducer( 7 | { 8 | key: 'cabenomeubolso', 9 | storage: AsyncStorage, 10 | whitelist: ['meta'], 11 | }, 12 | reducers 13 | ); 14 | return persistedReducer; 15 | }; 16 | -------------------------------------------------------------------------------- /src/services/bd/schemas/CabeItemSchema.ts: -------------------------------------------------------------------------------- 1 | import { ObjectSchema } from 'realm'; 2 | 3 | export default class CabeItemSchema { 4 | static schema: ObjectSchema = { 5 | name: 'CabeItem', 6 | primaryKey: 'id', 7 | properties: { 8 | id: { type: 'string', indexed: true }, 9 | name: 'string', 10 | quantity: 'int', 11 | value: { type: 'float', default: 0 }, 12 | done: { type: 'bool', default: false }, 13 | }, 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /ios/cabenomeubolso/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ios/cabenomeubolso/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | cabenomeubolso 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/config/ReactotronConfig.ts: -------------------------------------------------------------------------------- 1 | import Reactotron from 'reactotron-react-native'; 2 | import { reactotronRedux } from 'reactotron-redux'; 3 | import sagaPlugin from 'reactotron-redux-saga'; 4 | 5 | if (__DEV__) { 6 | const tron = Reactotron.configure() 7 | .useReactNative() 8 | .use(reactotronRedux()) 9 | .use(sagaPlugin({})) 10 | .connect(); 11 | 12 | tron.clear(); 13 | 14 | console.tron = tron; 15 | } else { 16 | console.tron = { 17 | log: () => {}, 18 | error: () => {}, 19 | logImportant: () => {}, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/ShimmerLoading/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Shimmer from 'react-native-shimmer'; 3 | 4 | import { Container, Title, Description, TextContainer } from './styles'; 5 | 6 | const ShimmerLoading: React.FC = () => { 7 | return ( 8 | 9 | 10 | 11 | Cabe no Meu Bolso 12 | Carregando... 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export default ShimmerLoading; 20 | -------------------------------------------------------------------------------- /src/store/modules/meta/reducer.ts: -------------------------------------------------------------------------------- 1 | import produce from 'immer'; 2 | import { Action } from 'redux'; 3 | 4 | import { TYPES } from './actions'; 5 | 6 | export type State = { 7 | introViewed: boolean; 8 | }; 9 | 10 | const INITIAL_STATE: State = { 11 | introViewed: false, 12 | }; 13 | 14 | export default function meta(state = INITIAL_STATE, action: Action) { 15 | return produce(state, draft => { 16 | switch (action.type) { 17 | case TYPES.markIntroAsViewed: 18 | draft.introViewed = true; 19 | break; 20 | default: 21 | } 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /src/services/bd/schemas/CabeSchema.ts: -------------------------------------------------------------------------------- 1 | import { ObjectSchema } from 'realm'; 2 | 3 | export default class CabeSchema { 4 | static schema: ObjectSchema = { 5 | name: 'Cabe', 6 | primaryKey: 'id', 7 | properties: { 8 | id: { type: 'string', indexed: true }, 9 | createdAt: { type: 'date', default: new Date() }, 10 | name: 'string', 11 | value: 'float', 12 | usedValue: { type: 'float', default: 0 }, 13 | items: 'CabeItem[]', 14 | finalized: { type: 'bool', default: false }, 15 | finalizedAt: { type: 'date', optional: true }, 16 | }, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/pages/CabeSave/components/FloatingBottomContainer/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import { Platform, SafeAreaView } from 'react-native'; 3 | 4 | import { Container } from './styles'; 5 | 6 | type Props = { 7 | children: React.ReactChild | React.ReactChildren | React.ReactElement; 8 | }; 9 | 10 | function FloatingBottomContainer({ children }: Props) { 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | } 17 | 18 | export default memo(FloatingBottomContainer); 19 | -------------------------------------------------------------------------------- /src/routes.tsx: -------------------------------------------------------------------------------- 1 | import { createAppContainer } from 'react-navigation'; 2 | import { createStackNavigator } from 'react-navigation-stack'; 3 | 4 | import Main from 'pages/Main'; 5 | import CabeSave from 'pages/CabeSave'; 6 | import CabeProcess from 'pages/CabeProcess'; 7 | import FinalizedCabeView from 'pages/FinalizedCabeView'; 8 | 9 | const Routes = createAppContainer( 10 | createStackNavigator( 11 | { 12 | Main, 13 | CabeSave, 14 | CabeProcess, 15 | FinalizedCabeView, 16 | }, 17 | { 18 | headerMode: 'none', 19 | } 20 | ) 21 | ); 22 | 23 | export default Routes; 24 | -------------------------------------------------------------------------------- /src/services/NavigationService.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NavigationActions, 3 | NavigationParams, 4 | NavigationContainerComponent, 5 | } from 'react-navigation'; 6 | 7 | let navigator: NavigationContainerComponent; 8 | 9 | function setTopLevelNavigator(navigatorRef: NavigationContainerComponent) { 10 | navigator = navigatorRef; 11 | } 12 | 13 | function navigate(routeName: string, params?: NavigationParams) { 14 | if (navigator) { 15 | navigator.dispatch( 16 | NavigationActions.navigate({ 17 | routeName, 18 | params, 19 | }) 20 | ); 21 | } 22 | } 23 | 24 | export default { 25 | navigate, 26 | setTopLevelNavigator, 27 | }; 28 | -------------------------------------------------------------------------------- /src/pages/Main/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { RootStore } from 'store/modules/rootReducer'; 4 | import Intro from 'pages/Intro'; 5 | import CabesList from 'pages/CabesList'; 6 | import RNBootSplash from 'react-native-bootsplash'; 7 | 8 | // import { Container } from './styles'; 9 | 10 | export default function Main() { 11 | const introViewed = useSelector((state: RootStore) => state.meta.introViewed); 12 | 13 | useEffect(() => { 14 | RNBootSplash.hide({ duration: 250 }); 15 | }, []); 16 | 17 | if (introViewed) { 18 | return ; 19 | } 20 | 21 | return ; 22 | } 23 | -------------------------------------------------------------------------------- /android/app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /src/pages/CabeSave/CabeName/styles.ts: -------------------------------------------------------------------------------- 1 | import { Input as DefaultInput } from 'react-native-elements'; 2 | import styled from 'styled-components/native'; 3 | import Color from 'color'; 4 | 5 | import colors from 'styles/colors'; 6 | 7 | export const DescriptionContainer = styled.View` 8 | margin: 15px; 9 | padding-bottom: 15px; 10 | border-bottom-width: 1px; 11 | border-bottom-color: ${Color(colors.c200) 12 | .lighten(0.3) 13 | .hex()}; 14 | `; 15 | 16 | export const DescriptionText = styled.Text` 17 | color: ${Color(colors.n100) 18 | .darken(0.7) 19 | .hex()}; 20 | font-size: 16px; 21 | margin-bottom: 5px; 22 | text-align: center; 23 | font-weight: bold; 24 | `; 25 | 26 | export const Input = styled(DefaultInput).attrs({})``; 27 | -------------------------------------------------------------------------------- /src/pages/CabeSave/CabeValue/styles.ts: -------------------------------------------------------------------------------- 1 | import { Input as DefaultInput } from 'react-native-elements'; 2 | import styled from 'styled-components/native'; 3 | 4 | import Color from 'color'; 5 | 6 | import colors from 'styles/colors'; 7 | 8 | export const DescriptionContainer = styled.View` 9 | margin: 15px; 10 | padding-bottom: 15px; 11 | border-bottom-width: 1px; 12 | border-bottom-color: ${Color(colors.c200) 13 | .lighten(0.3) 14 | .hex()}; 15 | `; 16 | 17 | export const DescriptionText = styled.Text` 18 | color: ${Color(colors.n100) 19 | .darken(0.7) 20 | .hex()}; 21 | font-size: 16px; 22 | margin-bottom: 5px; 23 | `; 24 | 25 | export const Input = styled(DefaultInput).attrs({ 26 | inputStyle: { 27 | textAlign: 'right', 28 | }, 29 | })``; 30 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import createSagaMiddleware from 'redux-saga'; 2 | import { persistStore } from 'redux-persist'; 3 | 4 | import createStore from './createStore'; 5 | import persistReducers from './persistReducers'; 6 | 7 | import rootReducer from './modules/rootReducer'; 8 | import rootSaga from './modules/rootSaga'; 9 | 10 | const sagaMonitor = 11 | process.env.NODE_ENV === 'development' 12 | ? console.tron.createSagaMonitor() 13 | : null; 14 | 15 | const sagaMiddleware = createSagaMiddleware({ sagaMonitor }); 16 | 17 | const middlewares = [sagaMiddleware]; 18 | 19 | const store: any = createStore(persistReducers(rootReducer), middlewares); 20 | const persistor = persistStore(store); 21 | 22 | sagaMiddleware.run(rootSaga); 23 | 24 | export { store, persistor }; 25 | -------------------------------------------------------------------------------- /src/pages/CabeProcess/CabeItemQuantity/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | import Color from 'color'; 3 | import { Input as DefaultInput } from 'react-native-elements'; 4 | 5 | import colors from 'styles/colors'; 6 | 7 | export const DescriptionContainer = styled.View` 8 | margin: 15px; 9 | padding-bottom: 15px; 10 | border-bottom-width: 1px; 11 | border-bottom-color: ${Color(colors.c200) 12 | .lighten(0.3) 13 | .hex()}; 14 | `; 15 | 16 | export const DescriptionText = styled.Text` 17 | color: ${Color(colors.n100) 18 | .darken(0.7) 19 | .hex()}; 20 | font-size: 16px; 21 | margin-bottom: 5px; 22 | `; 23 | 24 | export const Input = styled(DefaultInput).attrs({ 25 | inputStyle: { 26 | textAlign: 'right', 27 | }, 28 | })``; 29 | -------------------------------------------------------------------------------- /ios/cabenomeubolso/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /src/components/ShimmerLoading/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | 3 | import colors from 'styles/colors'; 4 | 5 | export const Container = styled.View` 6 | flex: 1; 7 | background-color: #fff; 8 | justify-content: center; 9 | align-items: center; 10 | position: absolute; 11 | top: 0; 12 | left: 0; 13 | right: 0; 14 | bottom: 0; 15 | z-index: 999; 16 | `; 17 | 18 | export const TextContainer = styled.View` 19 | justify-content: center; 20 | align-items: center; 21 | `; 22 | 23 | export const Title = styled.Text` 24 | font-size: 24px; 25 | color: ${colors.c400}; 26 | text-align: center; 27 | `; 28 | 29 | export const Description = styled.Text` 30 | font-size: 14px; 31 | color: ${colors.n900}; 32 | text-align: center; 33 | padding-top: 30px; 34 | `; 35 | -------------------------------------------------------------------------------- /ios/cabenomeubolsoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/cabenomeubolso-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /privacy.md: -------------------------------------------------------------------------------- 1 | ## Política de privacidade para o app **Cabe no Meu Bolso** 2 | 3 | Todas as suas informações pessoais recolhidas, quando forem, serão usadas para ajudar a tornar o seu uso do nosso app o mais produtivo e agradável possível. 4 | 5 | A garantia da confidencialidade dos dados pessoais dos utilizadores do nosso app é importante para o Cabe no Meu Bolso. 6 | 7 | Todas as informações pessoais relativas a membros, assinantes, clientes ou visitantes que usem o Cabe no Meu Bolso serão tratadas em concordância com a Lei da Proteção de Dados Pessoais de 26 de outubro de 1998 (Lei n.º 67/98). 8 | 9 | A informação pessoal recolhida pode incluir o seu nome, e-mail e/ou data de nascimento. 10 | 11 | O uso do Cabe no Meu Bolso pressupõe a aceitação deste Acordo de privacidade. A equipe do Cabe no Meu Bolso reserva-se ao direito de alterar este acordo sem aviso prévio. Deste modo, recomendamos que consulte a nossa política de privacidade com regularidade de forma a estar sempre atualizado. 12 | -------------------------------------------------------------------------------- /src/pages/Intro/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | import LinearGradient from 'react-native-linear-gradient'; 3 | import colors from 'styles/colors'; 4 | 5 | export const SlideContainer = styled(LinearGradient)` 6 | flex: 1; 7 | `; 8 | 9 | export const SlideContent = styled.SafeAreaView` 10 | flex: 1; 11 | justify-content: center; 12 | align-items: center; 13 | padding: 40px; 14 | `; 15 | 16 | export const SlideTitle = styled.Text` 17 | font-size: 22px; 18 | color: ${colors.n100}; 19 | font-weight: 700; 20 | text-align: center; 21 | margin-bottom: 10px; 22 | `; 23 | 24 | export const SlideSubtitle = styled.Text` 25 | font-size: 18px; 26 | color: ${colors.n100}; 27 | font-weight: 700; 28 | text-align: center; 29 | margin-bottom: 10px; 30 | opacity: 0.9; 31 | `; 32 | 33 | export const SlideDescription = styled.Text` 34 | font-size: 16px; 35 | color: ${colors.n100}; 36 | font-weight: 400; 37 | text-align: center; 38 | opacity: 0.9; 39 | `; 40 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useAndroidX=true 21 | android.enableJetifier=true 22 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import 'react-native-gesture-handler'; 4 | import 'config/ReactotronConfig'; 5 | import 'react-native-get-random-values'; 6 | 7 | import { Provider } from 'react-redux'; 8 | import { ThemeProvider } from 'react-native-elements'; 9 | import CodePush from 'react-native-code-push'; 10 | import { PersistGate } from 'redux-persist/integration/react'; 11 | 12 | import { store, persistor } from 'store'; 13 | import Routes from 'routes'; 14 | import NavigationService from 'services/NavigationService'; 15 | 16 | const App = () => ( 17 | 18 | 19 | 20 | { 22 | if (navigatorRef) { 23 | NavigationService.setTopLevelNavigator(navigatorRef); 24 | } 25 | }} 26 | /> 27 | 28 | 29 | 30 | ); 31 | 32 | export default CodePush({ 33 | checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME, 34 | })(App); 35 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "28.0.3" 6 | minSdkVersion = 16 7 | compileSdkVersion = 28 8 | targetSdkVersion = 28 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.4.2") 16 | 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | mavenLocal() 25 | maven { 26 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 27 | url("$rootDir/../node_modules/react-native/android") 28 | } 29 | maven { 30 | // Android JSC is installed from npm 31 | url("$rootDir/../node_modules/jsc-android/dist") 32 | } 33 | 34 | google() 35 | jcenter() 36 | maven { url 'https://jitpack.io' } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # Visual Studio Code 34 | # 35 | .vscode/ 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | !debug.keystore 48 | 49 | # fastlane 50 | # 51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 52 | # screenshots whenever they are needed. 53 | # For more information about the recommended setup visit: 54 | # https://docs.fastlane.tools/best-practices/source-control/ 55 | 56 | */fastlane/report.xml 57 | */fastlane/Preview.html 58 | */fastlane/screenshots 59 | 60 | # Bundle artifact 61 | *.jsbundle 62 | 63 | # CocoaPods 64 | /ios/Pods/ 65 | 66 | .vscode/ 67 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | // TODO fix bug: this code is breaking development environment and 4 | // is needed for release builds 5 | // if (process.env.NODE_ENV !== 'development') { 6 | // console.log('passa aqui') 7 | // return { 8 | // presets: ['module:metro-react-native-babel-preset'], 9 | // plugins: [ 10 | // 'transform-remove-console', 11 | // 'ignite-ignore-reactotron', 12 | // [ 13 | // 'module-resolver', 14 | // { 15 | // root: ['./src'], 16 | // extensions: [ 17 | // '.ios.js', 18 | // '.android.js', 19 | // '.js', 20 | // '.ts', 21 | // '.tsx', 22 | // '.json', 23 | // ], 24 | // }, 25 | // ], 26 | // ], 27 | // }; 28 | // } 29 | return { 30 | presets: ['module:metro-react-native-babel-preset'], 31 | plugins: [ 32 | [ 33 | 'module-resolver', 34 | { 35 | root: ['./src'], 36 | extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'], 37 | }, 38 | ], 39 | ], 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /src/pages/CabeProcess/CabeItemValue/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | import Color from 'color'; 3 | import { Input as DefaultInput } from 'react-native-elements'; 4 | 5 | import colors from 'styles/colors'; 6 | 7 | export const DescriptionContainer = styled.View` 8 | margin: 15px; 9 | padding-bottom: 15px; 10 | border-bottom-width: 1px; 11 | border-bottom-color: ${Color(colors.c200) 12 | .lighten(0.3) 13 | .hex()}; 14 | `; 15 | 16 | export const DescriptionText = styled.Text` 17 | color: ${Color(colors.n100) 18 | .darken(0.7) 19 | .hex()}; 20 | font-size: 16px; 21 | margin-bottom: 5px; 22 | `; 23 | 24 | export const Input = styled(DefaultInput).attrs({ 25 | inputStyle: { 26 | textAlign: 'right', 27 | }, 28 | })``; 29 | 30 | export const QuantityText = styled.Text` 31 | margin-top: 5px; 32 | text-align: center; 33 | font-size: 12px; 34 | font-weight: 400; 35 | color: ${Color(colors.n100) 36 | .darken(0.8) 37 | .hex()}; 38 | `; 39 | 40 | export const TotalValue = styled.Text` 41 | text-align: center; 42 | margin-top: 15px; 43 | padding: 5px 0; 44 | font-size: 16px; 45 | font-weight: 500; 46 | color: ${Color(colors.n100) 47 | .darken(0.8) 48 | .hex()}; 49 | `; 50 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/pages/CabeSave/CabeItemsList/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components/native'; 2 | import Color from 'color'; 3 | import colors from 'styles/colors'; 4 | 5 | export const DescriptionContainer = styled.View` 6 | margin: 15px; 7 | padding-bottom: 15px; 8 | border-bottom-color: ${Color(colors.c200) 9 | .lighten(0.3) 10 | .hex()}; 11 | border-bottom-width: 1px; 12 | `; 13 | 14 | export const DescriptionLine = styled.Text` 15 | color: ${Color(colors.n100) 16 | .darken(0.7) 17 | .hex()}; 18 | font-size: 16px; 19 | margin-bottom: 5px; 20 | `; 21 | 22 | export const EmptyList = styled.Text` 23 | text-align: center; 24 | margin-top: 15px; 25 | font-size: 18px; 26 | `; 27 | 28 | export const SwipeableContainer = styled.View` 29 | height: 100%; 30 | flex-direction: row; 31 | justify-content: space-between; 32 | align-items: center; 33 | `; 34 | 35 | export const LeftSwipeableItem = styled.View` 36 | flex: 1; 37 | align-items: flex-start; 38 | background-color: green; 39 | `; 40 | 41 | export const SwipeableItemContent = styled.View` 42 | height: 100%; 43 | width: 75; 44 | /* backgroundColor: 'green', */ 45 | align-items: center; 46 | justify-content: center; 47 | `; 48 | 49 | export const RightSwipeableItem = styled.View` 50 | flex: 1; 51 | align-items: flex-end; 52 | background-color: red; 53 | `; 54 | -------------------------------------------------------------------------------- /src/components/NumericKeyboard/styles.ts: -------------------------------------------------------------------------------- 1 | import DefaultLinearGradient from 'react-native-linear-gradient'; 2 | import styled from 'styled-components/native'; 3 | 4 | import Color from 'color'; 5 | 6 | import colors from 'styles/colors'; 7 | 8 | export const Container = styled.View` 9 | background-color: ${Color(colors.c200) 10 | .lighten(0.4) 11 | .hex()}; 12 | max-height: 40%; 13 | padding-bottom: 1px; 14 | `; 15 | 16 | export const Row = styled.View` 17 | flex-direction: row; 18 | margin-bottom: 1px; 19 | margin-top: 1px; 20 | height: 24.5%; 21 | 22 | &:last-child { 23 | margin-bottom: 0; 24 | } 25 | &:first-child { 26 | margin-top: 0; 27 | } 28 | `; 29 | 30 | export const Key = styled.TouchableOpacity.attrs({ 31 | activeOpacity: 0.7, 32 | })` 33 | flex: 1; 34 | margin-right: 1px; 35 | margin-left: 1px; 36 | 37 | &:last-child { 38 | margin-right: 0; 39 | } 40 | &:first-child { 41 | margin-left: 0; 42 | } 43 | `; 44 | 45 | export const LinearGradient = styled(DefaultLinearGradient).attrs({ 46 | colors: [colors.c300, colors.c200], 47 | start: { x: -0.5, y: 0 }, 48 | end: { x: 1, y: 1 }, 49 | })` 50 | flex: 1; 51 | justify-content: center; 52 | align-items: center; 53 | `; 54 | 55 | export const KeyText = styled.Text` 56 | color: ${colors.n100}; 57 | font-weight: bold; 58 | font-size: 26px; 59 | `; 60 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/cabenomeubolso/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.cabenomeubolso; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.facebook.react.ReactActivity; 6 | import com.facebook.react.ReactActivityDelegate; 7 | import com.facebook.react.ReactRootView; 8 | import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; 9 | import com.zoontek.rnbootsplash.RNBootSplash; 10 | 11 | public class MainActivity extends ReactActivity { 12 | 13 | /** 14 | * Returns the name of the main component registered from JavaScript. This is 15 | * used to schedule rendering of the component. 16 | */ 17 | @Override 18 | protected String getMainComponentName() { 19 | return "cabenomeubolso"; 20 | } 21 | 22 | @Override 23 | protected ReactActivityDelegate createReactActivityDelegate() { 24 | return new ReactActivityDelegate(this, getMainComponentName()) { 25 | @Override 26 | protected ReactRootView createRootView() { 27 | return new RNGestureHandlerEnabledRootView(MainActivity.this); 28 | } 29 | }; 30 | } 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | RNBootSplash.show(R.drawable.bootsplash, MainActivity.this); // <- display the "bootsplash" xml view over our 36 | // MainActivity 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cabe no Meu Bolso 2 | 3 | O Cabe no Meu bolso é um aplicativo que te ajuda a fazer compras dentro do seu orçamento. 4 | 5 | Nele, você cria listas de compras para se guiar no momento da compra, com quantidades de itens, preços e uma interface simples, amigável, fácil de utilizar e intuitiva. 6 | 7 | Utilizando o Cabe no Meu Bolso, você não tem mais surpresas na conta do caixa. 8 | 9 | ## Motivação 10 | 11 | Costumeiramente, acontecia de haver a necessidade de fazer compras baseado em uma lista de itens, e ter um orçamento fixo. Ex: Dada uma lista de compras, posso gastar R$ 400. Na hora da compra, preciso ficar fazendo as contas para garantir que o total não ultrapassasse esse valor. Além disso, precisava saber se poderia colocar mais itens ou maiores quantidades de um dado item. Assim nasceu a ideia do Cabe no Meu Bolso. 12 | 13 | ## Onde baixar? 14 | 15 | Baixe agora nosso app: 16 | 17 | [Download para Android](https://play.google.com/store/apps/details?id=com.cabenomeubolso) 18 | 19 | ## ROADMAP 20 | 21 | O que vem por aí? 22 | 23 | - [x] Adição da tela de boas-vindas/intro 24 | - [ ] Melhorias de design, como inclusão de modo dark, melhoramentos no logotipo, etc. 25 | - [ ] Criação de API backend para sincronização de listas na conta de usuário 26 | - [ ] Inserção de itens na hora da compra 27 | - [ ] Lixeira para listas apagadas 28 | - [ ] Listas de compras recorrentes 29 | - e mais... 30 | 31 | ## Política de privacidade 32 | 33 | Para ver nossa política de privacidade, [clique aqui](PRIVACY.md). 34 | -------------------------------------------------------------------------------- /android/app/_BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.cabenomeubolso", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.cabenomeubolso", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /ios/cabenomeubolso/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 19 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 20 | moduleName:@"cabenomeubolso" 21 | initialProperties:nil]; 22 | 23 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | UIViewController *rootViewController = [UIViewController new]; 27 | rootViewController.view = rootView; 28 | self.window.rootViewController = rootViewController; 29 | [self.window makeKeyAndVisible]; 30 | return YES; 31 | } 32 | 33 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /src/pages/CabeSave/CabeName/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Button } from 'components'; 4 | 5 | import { FloatingBottomContainer } from '../components'; 6 | 7 | import { DescriptionContainer, DescriptionText, Input } from './styles'; 8 | import { useCabeSave } from '../CabeSaveContext'; 9 | 10 | type Props = { 11 | nextStep: () => void; 12 | backStep: () => void; 13 | }; 14 | 15 | export default function CabeName({ nextStep, backStep }: Props) { 16 | const { 17 | cabeValue: { name }, 18 | setName, 19 | } = useCabeSave(); 20 | return ( 21 | <> 22 | 23 | Dê um nome a esse Cabe 24 | 25 | 26 | 35 | 36 | 37 | <> 38 | {!!name && ( 39 |