diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b804fc2..f7287e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,23 +4,40 @@ By participating in this project, you agree to abide by the debtors [code of con [code of conduct]: https://github.com/akuqt/debtors/blob/develop/CODE_OF_CONDUCT.md -Fork, then clone the repo: +[Fork][fork], then clone the repo: git clone https://github.com//debtors.git +[fork]: https://github.com/Akuqt/debtors/fork + System requirements: node >= 20.0.0 yarn >= 1.22.22 -Install dependencies: +Navigate to the project directory: + + cd debtors + +Install the dependencies: + + yarn install + +Link the repository to your eas account: + + eas init + +Generate a development build for your testing platform: + + eas build --platform [android | ios | all] --profile development + +Install the development build on your phone or emulator. - yarn +Start the application development server: -Make your change and make the lint and tests pass: + yarn start - yarn lint - yarn test +Use the development build to connect to the local server and start making changes. Push to your fork and [submit a pull request][pr]. @@ -31,7 +48,7 @@ some changes or improvements or alternatives. Some things that will increase the chance that your pull request is accepted: -- Write tests. +- Follow our Pull Request template. - Follow our [commit style][commit]. [commit]: https://www.conventionalcommits.org/en/v1.0.0/#specification diff --git a/README.md b/README.md index 8fb2967..992cb73 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,36 @@ -# Debtors - -## Overview +

+ Home Screen + Debtors +

Debtors is an application designed to help users manage and track their debtors. + + + + + + +
+ Home Screen + + Movements Screen + + Settings Screen +
+ ## Features -- Add new debt entries -- Edit existing debt entries -- Delete debt entries -- View a summary of total debts +- Quickly add new debtors with amount and description. +- Edit or delete existing debt entries. +- Group debtors using folders for better organization. +- Group movements using tags for easy categorization. +- View a summary of all debtors with total amounts. +- Export debtor summaries to PDF or XLSX formats. +- Support for multiple languages. +- Schedule automated notifications for debtors. +- Use advanced filters to search and manage entries. +- Import and export the full database for backup or migration. ## Technologies Used @@ -19,6 +40,12 @@ Debtors is an application designed to help users manage and track their debtors. - [Reanimated](https://docs.swmansion.com/react-native-reanimated/) - [i18next](https://www.i18next.com) +## Download + +Right now the application is only available for Android due to pending testing on iOS. + +You can download the latest Android release [here][download]. + ## Local Development 1. Clone the repository: @@ -65,12 +92,39 @@ Debtors is an application designed to help users manage and track their debtors. For any questions or suggestions, please [open an issue][issue]. -[issue]: https://github.com/akuqt/debtors/issues - ## Contributing Contributions are welcome! See the [CONTRIBUTING](CONTRIBUTING.md) file for details. ## License -This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. +This project is licensed under the MIT License. + + Copyright (c) 2025 Italo Alfaro + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +## Notes + +Personal project inspired by the need of debtors tracking. + + + +[issue]: https://github.com/akuqt/debtors/issues +[download]: https://github.com/Akuqt/debtors/releases/latest diff --git a/app.config.js b/app.config.js index 3b4908c..0d80709 100644 --- a/app.config.js +++ b/app.config.js @@ -17,7 +17,7 @@ export default { android: { adaptiveIcon: { foregroundImage: "./src/assets/images/adaptive-icon.png", - backgroundColor: "#151718", + backgroundColor: "#FFFFFF", }, package: IS_PROD ? "com.akuqt.debtors" : "com.akuqt.debtors.dev", }, @@ -29,7 +29,7 @@ export default { image: "./src/assets/images/splash-icon.png", imageWidth: 200, resizeMode: "contain", - backgroundColor: "#151718", + backgroundColor: "#FFFFFF", dark: { image: "./src/assets/images/splash-icon.png", backgroundColor: "#151718", diff --git a/docs/home.jpeg b/docs/home.jpeg new file mode 100644 index 0000000..f2e040c Binary files /dev/null and b/docs/home.jpeg differ diff --git a/docs/icon.png b/docs/icon.png new file mode 100644 index 0000000..235032a Binary files /dev/null and b/docs/icon.png differ diff --git a/docs/movements.jpeg b/docs/movements.jpeg new file mode 100644 index 0000000..714f23a Binary files /dev/null and b/docs/movements.jpeg differ diff --git a/docs/settings.jpeg b/docs/settings.jpeg new file mode 100644 index 0000000..77cd701 Binary files /dev/null and b/docs/settings.jpeg differ diff --git a/package.json b/package.json index bf396e8..088d15c 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "expo-file-system": "~18.0.11", "expo-font": "~13.0.2", "expo-haptics": "~14.0.0", + "expo-image": "~2.0.7", "expo-insights": "~0.8.1", "expo-linking": "~7.0.5", "expo-localization": "~16.0.1", diff --git a/src/app/home/index.tsx b/src/app/home/index.tsx index 03cfb22..9e564a6 100644 --- a/src/app/home/index.tsx +++ b/src/app/home/index.tsx @@ -106,10 +106,6 @@ export default function Home() { ); dispatch({ type: "setLoading", payload: false }); dispatch({ type: "setFolders", payload: res }); - dispatch({ - type: "setTotal", - payload: res.reduce((acc, debtor) => acc + debtor.total, 0), - }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [], @@ -177,6 +173,24 @@ export default function Home() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [sorter, search, isFocused, searchFolder]); + useEffect(() => { + let stotal = 0; + if (!selecting || selected.length === 0) { + stotal = folders.reduce((acc, debtor) => acc + debtor.total, 0); + } else { + for (const id of selected) { + const debtor = folders + .flatMap((f) => f.debtors) + .find((d) => d.id === id); + debtor && (stotal += debtor.total); + } + } + dispatch({ + type: "setTotal", + payload: stotal, + }); + }, [selecting, selected, folders]); + const { keyboardHeight } = useKeyboardHeightGradualAnimation(); const footerAnimatedStyle = useAnimatedStyle(() => { @@ -725,11 +739,17 @@ export default function Home() { }, }} onLongPress={() => { + const ids = item.debtors.map((u) => u.id); if (!selecting) { dispatch({ type: "setSelecting", payload: true }); dispatch({ type: "setSelected", - payload: item.debtors.map((u) => u.id), + payload: ids, + }); + } else { + dispatch({ + type: "setSelected", + payload: [...selected, ...ids], }); } }} diff --git a/src/app/movements/index.tsx b/src/app/movements/index.tsx index a7bb5c7..f1209c3 100644 --- a/src/app/movements/index.tsx +++ b/src/app/movements/index.tsx @@ -115,6 +115,28 @@ export default function Movements() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [isFocused]); + useEffect(() => { + let stotal: ReturnType = { + debts: [0, 0], + payments: [0, 0], + remaining: 0, + }; + if (!selecting || selected.length === 0) { + stotal = getTotals(movements); + } else { + const smovements: Movement[] = []; + for (const id of selected) { + const movement = movements.find((m) => m.id === id); + movement && smovements.push(movement); + } + stotal = getTotals(smovements); + } + dispatch({ + type: "setTotal", + payload: stotal, + }); + }, [movements, selected, selecting]); + const { generatePDF, generateXLSX } = useReportGenerator(tl, lang); const { keyboardHeight } = useKeyboardHeightGradualAnimation(); @@ -187,7 +209,6 @@ export default function Movements() { }, }); } - dispatch({ type: "setTotal", payload: getTotals(res) }); dispatch({ type: "setMovements", payload: res }); dispatch({ type: "setLoading", payload: false }); }, diff --git a/src/app/settings/options/about/index.tsx b/src/app/settings/options/about/index.tsx index 19db00e..23066ad 100644 --- a/src/app/settings/options/about/index.tsx +++ b/src/app/settings/options/about/index.tsx @@ -1,9 +1,10 @@ +import icon_image from "@/assets/images/adaptive-icon.png"; import { ThemedText } from "@/components"; import { VARS } from "@/constants/var"; import { useColors, useLocales } from "@/hooks"; import { styles } from "@/styles/settings"; import { SettingsAboutLocales } from "@/types"; -import Icon from "@expo/vector-icons/MaterialCommunityIcons"; +import { Image } from "expo-image"; import React from "react"; import { useTranslation } from "react-i18next"; import { ScrollView, TouchableOpacity, View } from "react-native"; @@ -37,13 +38,15 @@ export default function About() { > {`Version: ${VARS.settings.VERSION}`} -