├── .dockerignore
├── .github
└── workflows
│ ├── docker-image-dev.yml
│ └── docker-image.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── back
├── .editorconfig
├── .env.example
├── .gitattributes
├── .gitignore
├── README.md
├── app
│ ├── Authorizations
│ │ └── TransactionTemplateAuthorization.php
│ ├── Console
│ │ ├── Commands
│ │ │ └── CreateFakeTransactions.php
│ │ └── Kernel.php
│ ├── Exceptions
│ │ ├── FireflyException.php
│ │ ├── GeneralException.php
│ │ └── Handler.php
│ ├── Helpers
│ │ └── Helpers.php
│ ├── Http
│ │ ├── Controllers
│ │ │ ├── AccountController.php
│ │ │ ├── Base
│ │ │ │ ├── BaseController.php
│ │ │ │ └── BaseControllerFirefly.php
│ │ │ ├── BudgetController.php
│ │ │ ├── CategoryController.php
│ │ │ ├── CurrencyController.php
│ │ │ ├── ProfileController.php
│ │ │ ├── TagController.php
│ │ │ ├── TransactionController.php
│ │ │ ├── TransactionTemplateController.php
│ │ │ ├── UserController.php
│ │ │ └── VersionController.php
│ │ ├── Kernel.php
│ │ └── Middleware
│ │ │ ├── Authenticate.php
│ │ │ ├── EncryptCookies.php
│ │ │ ├── PreventRequestsDuringMaintenance.php
│ │ │ ├── RedirectIfAuthenticated.php
│ │ │ ├── TrimStrings.php
│ │ │ ├── TrustHosts.php
│ │ │ ├── TrustProxies.php
│ │ │ ├── ValidateSignature.php
│ │ │ └── VerifyCsrfToken.php
│ ├── Models
│ │ ├── Account.php
│ │ ├── BaseModel.php
│ │ ├── Budget.php
│ │ ├── Category.php
│ │ ├── Currency.php
│ │ ├── Icon.php
│ │ ├── Profile.php
│ │ ├── Tag.php
│ │ ├── Transaction.php
│ │ ├── TransactionTemplate.php
│ │ ├── TransactionTemplateExtraName.php
│ │ ├── TransactionTemplateTag.php
│ │ └── User.php
│ ├── Providers
│ │ ├── AppServiceProvider.php
│ │ ├── AuthServiceProvider.php
│ │ ├── BroadcastServiceProvider.php
│ │ ├── EventServiceProvider.php
│ │ └── RouteServiceProvider.php
│ ├── Repositories
│ │ ├── BaseRepository.php
│ │ └── TransactionTemplateRepository.php
│ ├── Utils
│ │ ├── CurrencyUtils.php
│ │ └── RouteUtils.php
│ └── Validations
│ │ └── TransactionTemplateValidation.php
├── artisan
├── bootstrap
│ ├── app.php
│ └── cache
│ │ └── .gitignore
├── composer.json
├── composer.lock
├── config
│ ├── app.php
│ ├── auth.php
│ ├── broadcasting.php
│ ├── cache.php
│ ├── cors.php
│ ├── database.php
│ ├── filesystems.php
│ ├── hashing.php
│ ├── logging.php
│ ├── mail.php
│ ├── queue.php
│ ├── services.php
│ ├── session.php
│ └── view.php
├── database
│ ├── .gitignore
│ ├── factories
│ │ └── UserFactory.php
│ ├── migrations
│ │ ├── 2014_10_12_000000_create_users_table.php
│ │ ├── 2014_10_12_100000_create_password_reset_tokens_table.php
│ │ ├── 2019_08_19_000000_create_failed_jobs_table.php
│ │ ├── 2019_12_14_000001_create_personal_access_tokens_table.php
│ │ ├── 2023_10_02_124513_create_transaction_templates.php
│ │ ├── 2024_02_22_131702_create_transaction_template_audio_names_table.php
│ │ ├── 2024_03_10_084308_create_tags_table.php
│ │ ├── 2024_03_27_130655_add_icon_to_accounts_and_categories.php
│ │ ├── 2024_04_01_121800_add_is_todo_to_tags.php
│ │ ├── 2024_04_23_155844_rename_transaction_templates_audio_names.php
│ │ ├── 2024_05_14_054224_add_is_visible_on_dashboard_to_accounts.php
│ │ ├── 2024_06_25_000000_create_profiles_table.php
│ │ └── 2024_09_13_152958_create_budgets_table.php
│ └── seeders
│ │ └── DatabaseSeeder.php
├── package-lock.json
├── package.json
├── phpunit.xml
├── public
│ ├── .htaccess
│ ├── favicon.ico
│ ├── index.php
│ └── robots.txt
├── resources
│ ├── css
│ │ └── app.css
│ ├── js
│ │ ├── app.js
│ │ └── bootstrap.js
│ └── views
│ │ └── welcome.blade.php
├── routes
│ ├── api.php
│ ├── channels.php
│ ├── console.php
│ └── web.php
├── storage
│ ├── app
│ │ ├── .gitignore
│ │ └── public
│ │ │ └── .gitignore
│ ├── framework
│ │ ├── .gitignore
│ │ ├── cache
│ │ │ ├── .gitignore
│ │ │ └── data
│ │ │ │ └── .gitignore
│ │ ├── sessions
│ │ │ └── .gitignore
│ │ ├── testing
│ │ │ └── .gitignore
│ │ └── views
│ │ │ └── .gitignore
│ └── logs
│ │ └── .gitignore
├── tests
│ ├── CreatesApplication.php
│ ├── Feature
│ │ └── ExampleTest.php
│ ├── TestCase.php
│ └── Unit
│ │ └── ExampleTest.php
└── vite.config.js
├── docker-compose.pico+firefly+importer.yml
├── docker-compose.pico+firefly.yml
├── docker-compose.pico.yml
├── docker
├── conf
│ ├── nginx
│ │ ├── http.d
│ │ │ └── default.conf
│ │ └── nginx.conf
│ ├── php-fpm
│ │ ├── php-fpm.conf
│ │ └── php-fpm.d
│ │ │ └── www.conf
│ └── supervisor
│ │ ├── cron.ini
│ │ ├── nginx.ini
│ │ ├── node.ini
│ │ ├── php-fpm.ini
│ │ └── supervisord.conf
└── docker-entrypoint.d
│ └── start.sh
├── docs
├── architecture.md
├── assistant.md
├── attribution.md
├── contribute.md
├── images
│ ├── architecture.png
│ ├── demo.gif
│ ├── logo.png
│ ├── logo2.png
│ └── presentation.png
└── installation.md
├── front
├── .gitignore
├── .npmrc
├── .prettierrc
├── README.md
├── app.vue
├── assets
│ ├── icons
│ │ ├── avatar
│ │ │ ├── actor-chaplin-comedy-svgrepo-com.svg
│ │ │ ├── addicted-draw-love-svgrepo-com.svg
│ │ │ ├── afro-avatar-male-2-svgrepo-com.svg
│ │ │ ├── afro-avatar-male-svgrepo-com.svg
│ │ │ ├── afro-boy-child-svgrepo-com.svg
│ │ │ ├── afro-female-person-svgrepo-com.svg
│ │ │ ├── alien-avatar-space-svgrepo-com.svg
│ │ │ ├── animal-avatar-bear-svgrepo-com.svg
│ │ │ ├── animal-avatar-mutton-svgrepo-com.svg
│ │ │ ├── animal-deer.svg
│ │ │ ├── animal-deer2.svg
│ │ │ ├── animal-dog.svg
│ │ │ ├── animal-elephant.svg
│ │ │ ├── animal-fox.svg
│ │ │ ├── animal-giraffe.svg
│ │ │ ├── animal-koala.svg
│ │ │ ├── animal-lion.svg
│ │ │ ├── animal-monkey.svg
│ │ │ ├── animal-monkey2.svg
│ │ │ ├── animal-owl.svg
│ │ │ ├── animal-racoon.svg
│ │ │ ├── animal-rhino.svg
│ │ │ ├── anime-away-face-svgrepo-com.svg
│ │ │ ├── apple-avatar-illness-svgrepo-com.svg
│ │ │ ├── artist-avatar-marilyn-svgrepo-com.svg
│ │ │ ├── atm.svg
│ │ │ ├── atm2.svg
│ │ │ ├── avatar-avocado-food-svgrepo-com.svg
│ │ │ ├── avatar-bad-breaking-svgrepo-com.svg
│ │ │ ├── avatar-batman-comics-svgrepo-com.svg
│ │ │ ├── avatar-boy-kid-svgrepo-com.svg
│ │ │ ├── avatar-boy-male-svgrepo-com.svg
│ │ │ ├── avatar-bug-insect-svgrepo-com.svg
│ │ │ ├── avatar-cacti-cactus-svgrepo-com.svg
│ │ │ ├── avatar-child-girl-svgrepo-com.svg
│ │ │ ├── avatar-cloud-crying-svgrepo-com.svg
│ │ │ ├── avatar-coffee-cup-svgrepo-com.svg
│ │ │ ├── avatar-dead-monster-svgrepo-com.svg
│ │ │ ├── avatar-einstein-professor-svgrepo-com.svg
│ │ │ ├── avatar-elderly-grandma-svgrepo-com.svg
│ │ │ ├── avatar-female-girl-svgrepo-com.svg
│ │ │ ├── avatar-female-portrait-2-svgrepo-com.svg
│ │ │ ├── avatar-female-portrait-svgrepo-com.svg
│ │ │ ├── avatar-geisha-japanese-svgrepo-com.svg
│ │ │ ├── avatar-hindi-indian-svgrepo-com.svg
│ │ │ ├── avatar-joker-squad-svgrepo-com.svg
│ │ │ ├── avatar-lazybones-sloth-svgrepo-com.svg
│ │ │ ├── avatar-male-man-svgrepo-com.svg
│ │ │ ├── avatar-male-ozzy-svgrepo-com.svg
│ │ │ ├── avatar-male-president-svgrepo-com.svg
│ │ │ ├── avatar-man-muslim-svgrepo-com.svg
│ │ │ ├── avatar-man-person-svgrepo-com.svg
│ │ │ ├── avatar-muslim-paranja-svgrepo-com.svg
│ │ │ ├── avatar-nun-sister-svgrepo-com.svg
│ │ │ ├── avatar-person-pilot-svgrepo-com.svg
│ │ │ ├── baby-child-kid-svgrepo-com.svg
│ │ │ ├── bag.svg
│ │ │ ├── bag2.svg
│ │ │ ├── bag3.svg
│ │ │ ├── bag4.svg
│ │ │ ├── bag5.svg
│ │ │ ├── bank-card-svgrepo-com.svg
│ │ │ ├── bank-finance-business-money-card-svgrepo-com.svg
│ │ │ ├── bank-svgrepo-com.svg
│ │ │ ├── bank.svg
│ │ │ ├── bank2.svg
│ │ │ ├── bar-chart-bars-chart-svgrepo-com.svg
│ │ │ ├── bar-chart-graph-svgrepo-com.svg
│ │ │ ├── bear-svgrepo-com.svg
│ │ │ ├── beard-hipster-male-svgrepo-com.svg
│ │ │ ├── bitcoin-svgrepo-com.svg
│ │ │ ├── box.svg
│ │ │ ├── boy-indian-kid-svgrepo-com.svg
│ │ │ ├── briefcase.svg
│ │ │ ├── briefcase2.svg
│ │ │ ├── browser-analytics-svgrepo-com.svg
│ │ │ ├── builder-helmet-worker-svgrepo-com.svg
│ │ │ ├── calculator.svg
│ │ │ ├── calendar-svgrepo-com.svg
│ │ │ ├── card.svg
│ │ │ ├── card2.svg
│ │ │ ├── chart-bar-chart-svgrepo-com.svg
│ │ │ ├── chart-decreasing-svgrepo-com.svg
│ │ │ ├── chart-graphic-svgrepo-com.svg
│ │ │ ├── child-girl-kid-svgrepo-com.svg
│ │ │ ├── christmas-clous-santa-svgrepo-com.svg
│ │ │ ├── coin-svgrepo-com.svg
│ │ │ ├── coin.svg
│ │ │ ├── coin2.svg
│ │ │ ├── coordinate-svgrepo-com.svg
│ │ │ ├── credit-card-svgrepo-com.svg
│ │ │ ├── diamond-ring-diamond-svgrepo-com.svg
│ │ │ ├── diamond.svg
│ │ │ ├── discount-sign-money-svgrepo-com.svg
│ │ │ ├── education.svg
│ │ │ ├── exchange.svg
│ │ │ ├── femal12.svg
│ │ │ ├── female.svg
│ │ │ ├── female10.svg
│ │ │ ├── female11.svg
│ │ │ ├── female13.svg
│ │ │ ├── female2.svg
│ │ │ ├── female3.svg
│ │ │ ├── female4.svg
│ │ │ ├── female5.svg
│ │ │ ├── female6.svg
│ │ │ ├── female7.svg
│ │ │ ├── female8.svg
│ │ │ ├── female9.svg
│ │ │ ├── fighter-luchador-man-svgrepo-com.svg
│ │ │ ├── football-svgrepo-com.svg
│ │ │ ├── friday-halloween-jason-svgrepo-com.svg
│ │ │ ├── globe-svgrepo-com.svg
│ │ │ ├── graph.svg
│ │ │ ├── heart-red-svgrepo-com.svg
│ │ │ ├── help-desk-svgrepo-com.svg
│ │ │ ├── indian-male-man-svgrepo-com.svg
│ │ │ ├── indian-man-sikh-svgrepo-com.svg
│ │ │ ├── light-bulb-idea-svgrepo-com.svg
│ │ │ ├── line-chart-svgrepo-com.svg
│ │ │ ├── male-man-old-svgrepo-com.svg
│ │ │ ├── male.svg
│ │ │ ├── male10.svg
│ │ │ ├── male11.svg
│ │ │ ├── male12.svg
│ │ │ ├── male13.svg
│ │ │ ├── male2.svg
│ │ │ ├── male3.svg
│ │ │ ├── male4.svg
│ │ │ ├── male5.svg
│ │ │ ├── male6.svg
│ │ │ ├── male7.svg
│ │ │ ├── male8.svg
│ │ │ ├── male9.svg
│ │ │ ├── medal-gold-svgrepo-com.svg
│ │ │ ├── money-cog.svg
│ │ │ ├── money-pile.svg
│ │ │ ├── money.svg
│ │ │ ├── money2.svg
│ │ │ ├── money3.svg
│ │ │ ├── money4.svg
│ │ │ ├── money5.svg
│ │ │ ├── payment-cards-money-svgrepo-com.svg
│ │ │ ├── phone.svg
│ │ │ ├── pie-chart-svgrepo-com.svg
│ │ │ ├── piggy-bank-svgrepo-com.svg
│ │ │ ├── piggy.svg
│ │ │ ├── piggy2.svg
│ │ │ ├── piggy3.svg
│ │ │ ├── piggy4.svg
│ │ │ ├── pot.svg
│ │ │ ├── pouch.svg
│ │ │ ├── pyramid-chart-graph-svgrepo-com.svg
│ │ │ ├── rainbow.svg
│ │ │ ├── safe.svg
│ │ │ ├── safe2.svg
│ │ │ ├── safebox-bank-svgrepo-com.svg
│ │ │ ├── shopping-bag-svgrepo-com.svg
│ │ │ ├── shopping-basket-svgrepo-com.svg
│ │ │ ├── star-gold-orange-svgrepo-com.svg
│ │ │ ├── statistics-graph-svgrepo-com.svg
│ │ │ ├── stats-line-chart-svgrepo-com.svg
│ │ │ ├── tag-price-label-svgrepo-com.svg
│ │ │ ├── target-hit-aim-svgrepo-com.svg
│ │ │ ├── umbrella.svg
│ │ │ ├── wallet-money-business-svgrepo-com.svg
│ │ │ ├── wallet-svgrepo-com-2.svg
│ │ │ ├── wallet-svgrepo-com.svg
│ │ │ ├── wallet.svg
│ │ │ └── wallet2.svg
│ │ ├── custom
│ │ │ └── exchange.svg
│ │ ├── duo
│ │ │ ├── adhesive-plaster-2.svg
│ │ │ ├── adhesive-plaster.svg
│ │ │ ├── airbuds-case.svg
│ │ │ ├── airbuds.svg
│ │ │ ├── alarm.svg
│ │ │ ├── album.svg
│ │ │ ├── archive-up-minimlistic.svg
│ │ │ ├── archive.svg
│ │ │ ├── armchair-2.svg
│ │ │ ├── armchair.svg
│ │ │ ├── asteroid.svg
│ │ │ ├── atom.svg
│ │ │ ├── backpack.svg
│ │ │ ├── bacteria.svg
│ │ │ ├── bag-2.svg
│ │ │ ├── bag-3.svg
│ │ │ ├── bag-4.svg
│ │ │ ├── bag-5.svg
│ │ │ ├── bag-heart.svg
│ │ │ ├── bag.svg
│ │ │ ├── balloon.svg
│ │ │ ├── balls.svg
│ │ │ ├── banknote-2.svg
│ │ │ ├── banknote.svg
│ │ │ ├── bar-chair.svg
│ │ │ ├── basketball.svg
│ │ │ ├── bath.svg
│ │ │ ├── battery-charge.svg
│ │ │ ├── bed.svg
│ │ │ ├── bedside-table-2.svg
│ │ │ ├── bedside-table-3.svg
│ │ │ ├── bedside-table-4.svg
│ │ │ ├── bedside-table.svg
│ │ │ ├── body.svg
│ │ │ ├── bolt-circle.svg
│ │ │ ├── bone.svg
│ │ │ ├── bonfire.svg
│ │ │ ├── book-bookmark-minimalistic.svg
│ │ │ ├── bookmark-square.svg
│ │ │ ├── bottle.svg
│ │ │ ├── bowling.svg
│ │ │ ├── box.svg
│ │ │ ├── calculator.svg
│ │ │ ├── calendar-add.svg
│ │ │ ├── calendar.svg
│ │ │ ├── camera-minimalistic.svg
│ │ │ ├── camera.svg
│ │ │ ├── card-2.svg
│ │ │ ├── card-recive.svg
│ │ │ ├── card-search.svg
│ │ │ ├── card-send.svg
│ │ │ ├── card-transfer.svg
│ │ │ ├── card.svg
│ │ │ ├── cardholder.svg
│ │ │ ├── cart-3.svg
│ │ │ ├── cart-check.svg
│ │ │ ├── cart.svg
│ │ │ ├── case-minimalistic.svg
│ │ │ ├── case-round.svg
│ │ │ ├── cash-out.svg
│ │ │ ├── cassette-2.svg
│ │ │ ├── chair-2.svg
│ │ │ ├── chair.svg
│ │ │ ├── chandelier.svg
│ │ │ ├── chart-2.svg
│ │ │ ├── chat--square-call.svg
│ │ │ ├── chat--square-like.svg
│ │ │ ├── chat--square.svg
│ │ │ ├── chef-hat-heart.svg
│ │ │ ├── chef-hat-minimalistic.svg
│ │ │ ├── clapperboard-edit.svg
│ │ │ ├── clapperboard-open-play.svg
│ │ │ ├── clapperboard-text.svg
│ │ │ ├── clipboard-heart.svg
│ │ │ ├── clipboard-list.svg
│ │ │ ├── closet-2.svg
│ │ │ ├── closet.svg
│ │ │ ├── cloud-bolt-minimalistic.svg
│ │ │ ├── cloud-rain.svg
│ │ │ ├── code.svg
│ │ │ ├── colour-tuneing.svg
│ │ │ ├── condicioner.svg
│ │ │ ├── confetti-minimalistic.svg
│ │ │ ├── corkscrew.svg
│ │ │ ├── cosmetic.svg
│ │ │ ├── cpu.svg
│ │ │ ├── crown-line.svg
│ │ │ ├── cup-first.svg
│ │ │ ├── cup-hot.svg
│ │ │ ├── cup-paper.svg
│ │ │ ├── cup.svg
│ │ │ ├── database.svg
│ │ │ ├── delivery.svg
│ │ │ ├── devices.svg
│ │ │ ├── diagram-down.svg
│ │ │ ├── diploma.svg
│ │ │ ├── diskette.svg
│ │ │ ├── display.svg
│ │ │ ├── dna.svg
│ │ │ ├── document-add.svg
│ │ │ ├── documents-minimalistic.svg
│ │ │ ├── dollar.svg
│ │ │ ├── donut-bitten.svg
│ │ │ ├── dumbbell-large.svg
│ │ │ ├── dumbbell-small.svg
│ │ │ ├── earth.svg
│ │ │ ├── emoji-funny-square.svg
│ │ │ ├── end-call-rounded.svg
│ │ │ ├── eraser.svg
│ │ │ ├── euro.svg
│ │ │ ├── eye.svg
│ │ │ ├── face-scan-square.svg
│ │ │ ├── filter.svg
│ │ │ ├── fire.svg
│ │ │ ├── flag.svg
│ │ │ ├── flame.svg
│ │ │ ├── flash-drive.svg
│ │ │ ├── flashlight-on.svg
│ │ │ ├── floor-lamp-minimalistic.svg
│ │ │ ├── floor-lamp.svg
│ │ │ ├── football.svg
│ │ │ ├── fridge.svg
│ │ │ ├── fuel.svg
│ │ │ ├── gallery-edit.svg
│ │ │ ├── gameboy.svg
│ │ │ ├── gamepad-charge.svg
│ │ │ ├── ghost-smile.svg
│ │ │ ├── gift.svg
│ │ │ ├── glasses.svg
│ │ │ ├── global.svg
│ │ │ ├── globus.svg
│ │ │ ├── golf.svg
│ │ │ ├── gps.svg
│ │ │ ├── hanger-2.svg
│ │ │ ├── hanger.svg
│ │ │ ├── headphones-round-sound.svg
│ │ │ ├── headphones-square.svg
│ │ │ ├── health.svg
│ │ │ ├── heart.svg
│ │ │ ├── hiking.svg
│ │ │ ├── history-3.svg
│ │ │ ├── home-angle-2.svg
│ │ │ ├── hourglass-line.svg
│ │ │ ├── inbox-archive.svg
│ │ │ ├── inbox-in.svg
│ │ │ ├── incognito.svg
│ │ │ ├── iphone.svg
│ │ │ ├── jar-of-pills-2.svg
│ │ │ ├── jar-of-pills.svg
│ │ │ ├── key.svg
│ │ │ ├── keyboard.svg
│ │ │ ├── ladle.svg
│ │ │ ├── lamp.svg
│ │ │ ├── laptop.svg
│ │ │ ├── layers-minimalistic.svg
│ │ │ ├── leaf.svg
│ │ │ ├── lightbulb.svg
│ │ │ ├── lightning.svg
│ │ │ ├── like.svg
│ │ │ ├── lock-keyhole.svg
│ │ │ ├── magic-stick-2.svg
│ │ │ ├── magic-stick-3.svg
│ │ │ ├── magic-stick.svg
│ │ │ ├── magnet.svg
│ │ │ ├── magnifer.svg
│ │ │ ├── mailbox.svg
│ │ │ ├── map-arrow-up.svg
│ │ │ ├── map-point-wave.svg
│ │ │ ├── map.svg
│ │ │ ├── masks.svg
│ │ │ ├── medal-ribbon-star.svg
│ │ │ ├── medal-star-circle.svg
│ │ │ ├── medal-star-square.svg
│ │ │ ├── medical-kit.svg
│ │ │ ├── meditation-round.svg
│ │ │ ├── men.svg
│ │ │ ├── microphone-large.svg
│ │ │ ├── microphone.svg
│ │ │ ├── money-bag.svg
│ │ │ ├── monitor-camera.svg
│ │ │ ├── moon-fog.svg
│ │ │ ├── moon.svg
│ │ │ ├── mouse.svg
│ │ │ ├── music-note-2.svg
│ │ │ ├── music-note-3.svg
│ │ │ ├── notebook.svg
│ │ │ ├── notes-minimalistic.svg
│ │ │ ├── notification-unread-lines.svg
│ │ │ ├── oven-mitts.svg
│ │ │ ├── paint-roller.svg
│ │ │ ├── palette-round.svg
│ │ │ ├── pallete-2.svg
│ │ │ ├── panorama.svg
│ │ │ ├── paper-bin.svg
│ │ │ ├── paperclip.svg
│ │ │ ├── passport.svg
│ │ │ ├── paw.svg
│ │ │ ├── pen.svg
│ │ │ ├── perfume.svg
│ │ │ ├── pill.svg
│ │ │ ├── pin-list.svg
│ │ │ ├── pin.svg
│ │ │ ├── pipette.svg
│ │ │ ├── plain-2.svg
│ │ │ ├── planet-2.svg
│ │ │ ├── planet-3.svg
│ │ │ ├── plug-circle.svg
│ │ │ ├── presentation-graph.svg
│ │ │ ├── printer-2.svg
│ │ │ ├── printer.svg
│ │ │ ├── projector.svg
│ │ │ ├── pulse-2.svg
│ │ │ ├── qr-code.svg
│ │ │ ├── radar-2.svg
│ │ │ ├── radio-minimalistic.svg
│ │ │ ├── radio.svg
│ │ │ ├── ranking.svg
│ │ │ ├── reel.svg
│ │ │ ├── remote-controller.svg
│ │ │ ├── rocket-2.svg
│ │ │ ├── rugby.svg
│ │ │ ├── ruler-angular.svg
│ │ │ ├── ruler-pen.svg
│ │ │ ├── ruler.svg
│ │ │ ├── running-2.svg
│ │ │ ├── scissors.svg
│ │ │ ├── server-path.svg
│ │ │ ├── server.svg
│ │ │ ├── settings.svg
│ │ │ ├── shop-2.svg
│ │ │ ├── sim-card-minimalistic.svg
│ │ │ ├── siren-rounded.svg
│ │ │ ├── skateboarding-round.svg
│ │ │ ├── skirt.svg
│ │ │ ├── sledgehammer.svg
│ │ │ ├── sleeping.svg
│ │ │ ├── smart-speaker-minimalistic.svg
│ │ │ ├── smart-vacuum-cleaner.svg
│ │ │ ├── snowflake.svg
│ │ │ ├── sofa-3.svg
│ │ │ ├── sofa.svg
│ │ │ ├── speaker.svg
│ │ │ ├── square-academic-cap.svg
│ │ │ ├── star.svg
│ │ │ ├── stars-line.svg
│ │ │ ├── station-minimalistic.svg
│ │ │ ├── stethoscope.svg
│ │ │ ├── stream.svg
│ │ │ ├── streets-map-point.svg
│ │ │ ├── stretching-round.svg
│ │ │ ├── suitcase-lines.svg
│ │ │ ├── suitcase-tag.svg
│ │ │ ├── suitcase.svg
│ │ │ ├── sun-2.svg
│ │ │ ├── swimming.svg
│ │ │ ├── syringe.svg
│ │ │ ├── t-shirt.svg
│ │ │ ├── tag.svg
│ │ │ ├── target.svg
│ │ │ ├── tea-cup.svg
│ │ │ ├── telescope.svg
│ │ │ ├── temperature.svg
│ │ │ ├── tennis-2.svg
│ │ │ ├── tennis.svg
│ │ │ ├── test-tube-minimalistic.svg
│ │ │ ├── thermometer.svg
│ │ │ ├── ticker-star.svg
│ │ │ ├── tornado-small.svg
│ │ │ ├── trash-bin-trash.svg
│ │ │ ├── treadmill.svg
│ │ │ ├── turntable.svg
│ │ │ ├── tv.svg
│ │ │ ├── ufo.svg
│ │ │ ├── umbrella.svg
│ │ │ ├── user.svg
│ │ │ ├── videocamera-record.svg
│ │ │ ├── volleyball.svg
│ │ │ ├── walking.svg
│ │ │ ├── wallet-money.svg
│ │ │ ├── wallet.svg
│ │ │ ├── wallpaper.svg
│ │ │ ├── washing-machine-minimalistic.svg
│ │ │ ├── washing-machine.svg
│ │ │ ├── watch-square.svg
│ │ │ ├── water-sun.svg
│ │ │ ├── water.svg
│ │ │ ├── waterdrop.svg
│ │ │ ├── waterdrops.svg
│ │ │ ├── weigher.svg
│ │ │ ├── whisk.svg
│ │ │ ├── wi-fi-router.svg
│ │ │ ├── wineglass-triangle.svg
│ │ │ ├── wineglass.svg
│ │ │ ├── wireless-charge.svg
│ │ │ └── women.svg
│ │ ├── flags
│ │ │ ├── cn.svg
│ │ │ ├── en.svg
│ │ │ ├── it.svg
│ │ │ └── ro.svg
│ │ ├── fluent
│ │ │ ├── bike.svg
│ │ │ ├── building_24_regular.svg
│ │ │ ├── building_bank_20_regular.svg
│ │ │ ├── building_home_16_regular.svg
│ │ │ ├── building_mosque_20_regular.svg
│ │ │ ├── building_multiple_20_regular.svg
│ │ │ ├── building_townhouse_20_regular.svg
│ │ │ ├── chick.svg
│ │ │ ├── crown_20_regular.svg
│ │ │ ├── dentist_20_regular.svg
│ │ │ ├── desktop_sync_24_regular.svg
│ │ │ ├── dishwasher_20_regular.svg
│ │ │ ├── dress.svg
│ │ │ ├── emoji_24_regular.svg
│ │ │ ├── food_24_regular.svg
│ │ │ ├── food_apple_20_regular.svg
│ │ │ ├── food_chicken_leg_16_regular.svg
│ │ │ ├── food_egg_20_regular.svg
│ │ │ ├── food_fish_20_regular.svg
│ │ │ ├── food_pizza_20_regular.svg
│ │ │ ├── food_toast_20_regular.svg
│ │ │ ├── glasses.svg
│ │ │ ├── hat.svg
│ │ │ ├── home_garage_20_regular.svg
│ │ │ ├── ice-cream.svg
│ │ │ ├── kid1.svg
│ │ │ ├── kid2.svg
│ │ │ ├── kid3.svg
│ │ │ ├── motorbike.svg
│ │ │ ├── pants.svg
│ │ │ ├── rocket_24_regular.svg
│ │ │ ├── savings_24_regular.svg
│ │ │ ├── school.svg
│ │ │ ├── scooter.svg
│ │ │ ├── scooter2.svg
│ │ │ ├── shifts_20_regular.svg
│ │ │ ├── shoe.svg
│ │ │ ├── spatula_spoon_24_regular.svg
│ │ │ ├── stack_star_20_regular.svg
│ │ │ ├── underwear.svg
│ │ │ ├── vehicle_bicycle_20_regular.svg
│ │ │ ├── vehicle_car_profile_24_regular.svg
│ │ │ ├── wallet_20_regular.svg
│ │ │ └── wifi.svg
│ │ └── speed1.svg
│ ├── styles
│ │ ├── animations.css
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap.min.css.map
│ │ ├── helper.css
│ │ ├── theme-dark.css
│ │ ├── theme.css
│ │ └── variables.css
│ └── svg
│ │ ├── empty.svg
│ │ └── empty2.svg
├── components
│ ├── account
│ │ └── account-adjust-balance.vue
│ ├── budget
│ │ └── budget-icon.vue
│ ├── charts
│ │ ├── bar-chart-item-horizontal.vue
│ │ └── bar-chart-item-vertical.vue
│ ├── dashboard
│ │ ├── dashboard-accounts
│ │ │ └── dashboard-accounts.vue
│ │ ├── dashboard-budgets
│ │ │ ├── dashboard-budget-item.vue
│ │ │ └── dashboard-budgets.vue
│ │ ├── dashboard-calendar
│ │ │ ├── dashboard-calendar-month-day.vue
│ │ │ ├── dashboard-calendar-month.vue
│ │ │ └── dashboard-calendar.vue
│ │ ├── dashboard-category-totals
│ │ │ └── dashboard-category-totals.vue
│ │ ├── dashboard-controls
│ │ │ ├── dashboard-control-buttons.vue
│ │ │ └── dashboard-control.vue
│ │ ├── dashboard-summary
│ │ │ ├── dashboard-summary-card.vue
│ │ │ └── dashboard-summary.vue
│ │ ├── dashboard-tag-totals
│ │ │ └── dashboard-tag-totals.vue
│ │ ├── dashboard-todo-transactions
│ │ │ └── dashboard-todo-transactions.vue
│ │ └── dashboard-week-bars
│ │ │ └── dashboard-week-bars.vue
│ ├── general
│ │ └── empty-list.vue
│ ├── global
│ │ └── svg
│ │ │ ├── SvgAccountIcon.vue
│ │ │ ├── SvgAccountTransfer.vue
│ │ │ ├── SvgAddIcon.vue
│ │ │ ├── SvgCategoryIcon.vue
│ │ │ ├── SvgEmptyList.vue
│ │ │ ├── SvgEmptyList2.vue
│ │ │ ├── SvgExtrasIcon.vue
│ │ │ ├── SvgSettingIcon.vue
│ │ │ ├── SvgTagIcon.vue
│ │ │ ├── SvgTransactionIcon.vue
│ │ │ └── SvgTransactionTemplateIcon.vue
│ ├── list-items
│ │ ├── account-list-item.vue
│ │ ├── app-list-item.vue
│ │ ├── budget-list-item.vue
│ │ ├── category-list-item.vue
│ │ ├── currency-list-item.vue
│ │ ├── tag-list-item.vue
│ │ ├── transaction-list-item-hero-icon.vue
│ │ ├── transaction-list-item.vue
│ │ └── transaction-template-list-item.vue
│ ├── select
│ │ ├── account
│ │ │ ├── account-liability-direction-select.vue
│ │ │ ├── account-liability-type-select.vue
│ │ │ ├── account-role-select.vue
│ │ │ ├── account-select.vue
│ │ │ └── account-type-select.vue
│ │ ├── budget-select.vue
│ │ ├── budget
│ │ │ ├── budget-period-select.vue
│ │ │ └── budget-type-select.vue
│ │ ├── category-select.vue
│ │ ├── currency-dropdown.vue
│ │ ├── currency-select.vue
│ │ ├── date-format-select.vue
│ │ ├── general
│ │ │ ├── day-select.vue
│ │ │ └── language-select.vue
│ │ ├── icon-select.vue
│ │ ├── page-select.vue
│ │ ├── tag-select.vue
│ │ ├── transaction-template-popup.vue
│ │ └── transaction-type-select.vue
│ ├── settings
│ │ ├── app-config-stat.vue
│ │ └── settings-token-field.vue
│ ├── transaction
│ │ ├── transaction-amount-field-operations.vue
│ │ ├── transaction-amount-field-success-animation.vue
│ │ ├── transaction-amount-field.vue
│ │ ├── transaction-assistant.vue
│ │ ├── transaction-filters.vue
│ │ ├── transaction-split-badge.vue
│ │ ├── transaction-type-dot.vue
│ │ └── transaction-type-tabs.vue
│ └── ui-kit
│ │ ├── app-action-sheet.vue
│ │ ├── app-boolean-old.vue
│ │ ├── app-boolean.vue
│ │ ├── app-checkbox.vue
│ │ ├── app-chip.vue
│ │ ├── app-circle.vue
│ │ ├── app-date-time-grid.vue
│ │ ├── app-date-time.vue
│ │ ├── app-date.vue
│ │ ├── app-field-link.vue
│ │ ├── app-field.vue
│ │ ├── app-icon.vue
│ │ ├── app-loading.vue
│ │ ├── app-month-year.vue
│ │ ├── app-repeater.vue
│ │ ├── app-select-option.vue
│ │ ├── app-select.vue
│ │ ├── app-tab-bar-item.vue
│ │ ├── app-time.vue
│ │ ├── app-tutorial.vue
│ │ └── theme
│ │ ├── app-bottom-loading.vue
│ │ ├── app-bottom-toolbar.vue
│ │ ├── app-button-form-delete.vue
│ │ ├── app-button-form-save.vue
│ │ ├── app-button-list-add.vue
│ │ ├── app-card-info.vue
│ │ ├── app-list-search.vue
│ │ └── app-top-toolbar.vue
├── composables
│ ├── directives
│ │ └── swipe-fix.js
│ ├── useActionSheet.js
│ ├── useClickWithoutSwipe.js
│ ├── useForm.js
│ ├── useFormAttributes.js
│ ├── useKeyboard.js
│ ├── useList.js
│ ├── useSpeechRecognition.js
│ ├── useSwipeToDismiss.js
│ └── useToolbar.js
├── constants
│ ├── Constants.js
│ ├── DashboardConstants.js
│ ├── LanguageConstants.js
│ ├── RouteConstants.js
│ ├── SvgConstants.js
│ ├── TablerIconConstants.js
│ ├── TransactionConstants.js
│ └── TutorialConstants.js
├── eslint.config.mjs
├── global.d.ts
├── i18n
│ ├── i18n.config.js
│ ├── index.js
│ └── locales
│ │ ├── en.json
│ │ ├── it.json
│ │ ├── ro.json
│ │ └── zh-CN.json
├── layouts
│ ├── default.vue
│ └── empty.vue
├── models
│ ├── Account.js
│ ├── BaseModel.js
│ ├── Budget.js
│ ├── BudgetLimit.js
│ ├── Category.js
│ ├── Currency.js
│ ├── Icon.js
│ ├── Page.js
│ ├── Profile.js
│ ├── Tag.js
│ ├── Transaction.js
│ └── TransactionTemplate.js
├── modules
│ └── register-components.js
├── nuxt.config.ts
├── package-lock.json
├── package.json
├── pages
│ ├── accounts
│ │ ├── [[id]].vue
│ │ └── list.vue
│ ├── budgets
│ │ ├── [[id]].vue
│ │ └── list.vue
│ ├── categories
│ │ ├── [[id]].vue
│ │ └── list.vue
│ ├── currencies
│ │ ├── [[id]].vue
│ │ └── list.vue
│ ├── dashboard.vue
│ ├── exchange-rates
│ │ └── index.vue
│ ├── extras.vue
│ ├── index.vue
│ ├── mihai.vue
│ ├── settings
│ │ ├── about.vue
│ │ ├── assistant.vue
│ │ ├── dashboard
│ │ │ ├── cards.vue
│ │ │ └── index.vue
│ │ ├── formatting.vue
│ │ ├── index.vue
│ │ ├── setup.vue
│ │ ├── transactions
│ │ │ ├── default-form-values.vue
│ │ │ ├── default-list-filters.vue
│ │ │ ├── form-fields.vue
│ │ │ ├── index.vue
│ │ │ ├── list-fields.vue
│ │ │ └── quick-amounts.vue
│ │ └── ui.vue
│ ├── tags
│ │ ├── [[id]].vue
│ │ └── list.vue
│ ├── transaction-templates
│ │ ├── [[id]].vue
│ │ └── list.vue
│ └── transactions
│ │ ├── [[id]].vue
│ │ └── list.vue
├── plugins
│ ├── array-extension.js
│ ├── axios.js
│ ├── plugin-date-fns.js
│ ├── plugin-i18n.js
│ ├── plugin-register-tabler-icons.js
│ └── plugin-vant.js
├── public
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── mstile-150x150.png
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
├── repository
│ ├── AccountRepository.js
│ ├── BaseRepository.js
│ ├── BudgetRepository.js
│ ├── CategoryRepository.js
│ ├── CurrencyRepository.js
│ ├── InfoRepository.js
│ ├── ProfileRepository.js
│ ├── TagRepository.js
│ ├── TransactionRepository.js
│ ├── TransactionTemplateRepository.js
│ └── UserRepository.js
├── stores
│ ├── appStore.js
│ ├── dataStore.js
│ └── profileStore.js
├── transformers
│ ├── AccountTransformer.js
│ ├── ApiTransformer.js
│ ├── BudgetLimitTransformer.js
│ ├── BudgetTransformer.js
│ ├── CategoryTransformer.js
│ ├── CurrencyTransformer.js
│ ├── ProfileTransformer.js
│ ├── TagTransformer.js
│ ├── TransactionTemplateTransformer.js
│ └── TransactionTransformer.js
├── tsconfig.json
└── utils
│ ├── AnimationUtils.js
│ ├── CurrencyUtils.js
│ ├── DashboardUtils.js
│ ├── DataUtils.js
│ ├── DateUtils.js
│ ├── FilterUtils.js
│ ├── LanguageUtils.js
│ ├── MathUtils.js
│ ├── MigrateUtils.js
│ ├── NumberUtils.js
│ ├── ResponseUtils.js
│ ├── RomanianLanguageUtils.js
│ ├── SettingUtils.js
│ ├── TransactionFilterUtils.js
│ ├── UIUtils.js
│ ├── Utils.js
│ ├── ValidationUtils.js
│ └── VueUtils.js
└── readme.md
/.dockerignore:
--------------------------------------------------------------------------------
1 | back/vendor
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log*
3 | .nuxt
4 | .nitro
5 | .cache
6 | .output
7 | .env
8 | dist
9 | .idea
10 | .vscode
11 |
--------------------------------------------------------------------------------
/back/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 4
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*.{yml,yaml}]
15 | indent_size = 2
16 |
17 | [docker-compose.yml]
18 | indent_size = 4
19 |
--------------------------------------------------------------------------------
/back/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
3 | *.blade.php diff=html
4 | *.css diff=css
5 | *.html diff=html
6 | *.md diff=markdown
7 | *.php diff=php
8 |
9 | /.github export-ignore
10 | CHANGELOG.md export-ignore
11 | .styleci.yml export-ignore
12 |
--------------------------------------------------------------------------------
/back/.gitignore:
--------------------------------------------------------------------------------
1 | /.phpunit.cache
2 | /node_modules
3 | /public/build
4 | /public/hot
5 | /public/storage
6 | /storage/*.key
7 | /vendor
8 | .env
9 | .env.backup
10 | .env.production
11 | .phpunit.result.cache
12 | Homestead.json
13 | Homestead.yaml
14 | auth.json
15 | npm-debug.log
16 | yarn-error.log
17 | /.fleet
18 | /.idea
19 | /.vscode
20 |
--------------------------------------------------------------------------------
/back/README.md:
--------------------------------------------------------------------------------
1 | ## Structure
--------------------------------------------------------------------------------
/back/app/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | command('inspire')->hourly();
16 | }
17 |
18 | /**
19 | * Register the commands for the application.
20 | */
21 | protected function commands(): void
22 | {
23 | $this->load(__DIR__.'/Commands');
24 |
25 | require base_path('routes/console.php');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/back/app/Http/Controllers/AccountController.php:
--------------------------------------------------------------------------------
1 | getFullUrl();
21 | $response = $this->getHttpClient()->get($url);
22 |
23 | if ($response->status() !== self::HTTP_CODE_OK) {
24 | throw new FireflyException($response);
25 | }
26 | $data = $response->json();
27 | $data = $this->onPostGet($data);
28 | return $data;
29 | }
30 |
31 | // ---------------------------
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/back/app/Http/Controllers/UserController.php:
--------------------------------------------------------------------------------
1 | expectsJson() ? null : route('login');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/EncryptCookies.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/PreventRequestsDuringMaintenance.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/RedirectIfAuthenticated.php:
--------------------------------------------------------------------------------
1 | check()) {
24 | return redirect(RouteServiceProvider::HOME);
25 | }
26 | }
27 |
28 | return $next($request);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/TrimStrings.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | 'current_password',
16 | 'password',
17 | 'password_confirmation',
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/TrustHosts.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | public function hosts(): array
15 | {
16 | return [
17 | $this->allSubdomainsOfApplicationUrl(),
18 | ];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/TrustProxies.php:
--------------------------------------------------------------------------------
1 | |string|null
14 | */
15 | protected $proxies;
16 |
17 | /**
18 | * The headers that should be used to detect proxies.
19 | *
20 | * @var int
21 | */
22 | protected $headers =
23 | Request::HEADER_X_FORWARDED_FOR |
24 | Request::HEADER_X_FORWARDED_HOST |
25 | Request::HEADER_X_FORWARDED_PORT |
26 | Request::HEADER_X_FORWARDED_PROTO |
27 | Request::HEADER_X_FORWARDED_AWS_ELB;
28 | }
29 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/ValidateSignature.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | // 'fbclid',
16 | // 'utm_campaign',
17 | // 'utm_content',
18 | // 'utm_medium',
19 | // 'utm_source',
20 | // 'utm_term',
21 | ];
22 | }
23 |
--------------------------------------------------------------------------------
/back/app/Http/Middleware/VerifyCsrfToken.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | protected $except = [
15 | //
16 | ];
17 | }
18 |
--------------------------------------------------------------------------------
/back/app/Models/Account.php:
--------------------------------------------------------------------------------
1 | 'array'
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/back/app/Models/Tag.php:
--------------------------------------------------------------------------------
1 | hasMany(TransactionTemplateTag::class);
25 | }
26 |
27 | // ------------------------------ Scopes ---------------------------------
28 |
29 | public function scopeSearch(Builder $query, $search = null)
30 | {
31 | if (!$search)
32 | return $query;
33 |
34 | return applyWhereLike($query, 'name', $search);
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/back/app/Models/TransactionTemplateExtraName.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | protected $policies = [
16 | //
17 | ];
18 |
19 | /**
20 | * Register any authentication / authorization services.
21 | */
22 | public function boot(): void
23 | {
24 | //
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/back/app/Providers/BroadcastServiceProvider.php:
--------------------------------------------------------------------------------
1 | where('id', '[0-9]+');
12 | Route::get($routeName, [$controller, 'getAll']);
13 |
14 | Route::post("$routeName", [$controller, 'create']);
15 | Route::patch("$routeName/{id}", [$controller, 'update'])->where('id', '[0-9]+');
16 | Route::put("$routeName/{id}", [$controller, 'update'])->where('id', '[0-9]+');
17 | Route::delete("$routeName/{id}", [$controller, 'delete'])->where('id', '[0-9]+');
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/back/app/Validations/TransactionTemplateValidation.php:
--------------------------------------------------------------------------------
1 | validate([
28 | 'name' => 'required|max:1000',
29 | // 'description' => 'nullable|max:10000',
30 | ]);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/back/bootstrap/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/back/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite*
2 |
--------------------------------------------------------------------------------
/back/database/migrations/2014_10_12_000000_create_users_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('name');
17 | $table->string('email')->unique();
18 | $table->timestamp('email_verified_at')->nullable();
19 | $table->string('password');
20 | $table->rememberToken();
21 | $table->timestamps();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('users');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/back/database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php:
--------------------------------------------------------------------------------
1 | string('email')->primary();
16 | $table->string('token');
17 | $table->timestamp('created_at')->nullable();
18 | });
19 | }
20 |
21 | /**
22 | * Reverse the migrations.
23 | */
24 | public function down(): void
25 | {
26 | Schema::dropIfExists('password_reset_tokens');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/back/database/migrations/2019_08_19_000000_create_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->string('uuid')->unique();
17 | $table->text('connection');
18 | $table->text('queue');
19 | $table->longText('payload');
20 | $table->longText('exception');
21 | $table->timestamp('failed_at')->useCurrent();
22 | });
23 | }
24 |
25 | /**
26 | * Reverse the migrations.
27 | */
28 | public function down(): void
29 | {
30 | Schema::dropIfExists('failed_jobs');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_02_22_131702_create_transaction_template_audio_names_table.php:
--------------------------------------------------------------------------------
1 | id();
14 | $table->timestamps();
15 | $table->unsignedBigInteger("transaction_template_id");
16 | $table->string("name", 1000);
17 | $table->foreign('transaction_template_id')->references('id')->on('transaction_templates')->onDelete('cascade');
18 | });
19 | }
20 |
21 |
22 | public function down(): void
23 | {
24 | Schema::dropIfExists('transaction_template_audio_names');
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_03_10_084308_create_tags_table.php:
--------------------------------------------------------------------------------
1 | id();
16 | $table->timestamps();
17 | $table->string("icon", 1000)->nullable();
18 | $table->integer("parent_id")->nullable();
19 | });
20 | }
21 |
22 | /**
23 | * Reverse the migrations.
24 | */
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('tags');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_04_01_121800_add_is_todo_to_tags.php:
--------------------------------------------------------------------------------
1 | boolean("is_todo")->default(false);
13 | });
14 | }
15 |
16 |
17 | public function down(): void
18 | {
19 | Schema::table('tags', function (Blueprint $table) {
20 | $table->dropColumn("is_todo");
21 | });
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_04_23_155844_rename_transaction_templates_audio_names.php:
--------------------------------------------------------------------------------
1 | boolean("is_dashboard_visible")->default(true);
14 | });
15 | }
16 |
17 |
18 | public function down(): void
19 | {
20 | Schema::table('accounts', function (Blueprint $table) {
21 | $table->dropColumn("is_dashboard_visible");
22 | });
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_06_25_000000_create_profiles_table.php:
--------------------------------------------------------------------------------
1 | id();
13 | $table->string("auth_token_hash")->unique();
14 | $table->jsonb('settings')->nullable();
15 | $table->timestamps();
16 | });
17 | }
18 |
19 |
20 | public function down(): void
21 | {
22 | Schema::dropIfExists('profiles');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/back/database/migrations/2024_09_13_152958_create_budgets_table.php:
--------------------------------------------------------------------------------
1 | id();
14 | $table->timestamps();
15 | $table->string("icon", 1000)->nullable();
16 | });
17 | }
18 |
19 |
20 | public function down(): void
21 | {
22 | Schema::dropIfExists('budgets');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/back/database/seeders/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 | create();
16 |
17 | // \App\Models\User::factory()->create([
18 | // 'name' => 'Test User',
19 | // 'email' => 'test@example.com',
20 | // ]);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/back/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "type": "module",
4 | "scripts": {
5 | "dev": "vite",
6 | "build": "vite build"
7 | },
8 | "devDependencies": {
9 | "axios": "^1.1.2",
10 | "laravel-vite-plugin": "^0.8.0",
11 | "vite": "^4.0.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/back/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Redirect Trailing Slashes If Not A Folder...
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 | RewriteCond %{REQUEST_URI} (.+)/$
15 | RewriteRule ^ %1 [L,R=301]
16 |
17 | # Send Requests To Front Controller...
18 | RewriteCond %{REQUEST_FILENAME} !-d
19 | RewriteCond %{REQUEST_FILENAME} !-f
20 | RewriteRule ^ index.php [L]
21 |
22 |
--------------------------------------------------------------------------------
/back/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/back/public/favicon.ico
--------------------------------------------------------------------------------
/back/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/back/resources/css/app.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/back/resources/css/app.css
--------------------------------------------------------------------------------
/back/resources/js/app.js:
--------------------------------------------------------------------------------
1 | import './bootstrap';
2 |
--------------------------------------------------------------------------------
/back/routes/channels.php:
--------------------------------------------------------------------------------
1 | id === (int) $id;
18 | });
19 |
--------------------------------------------------------------------------------
/back/routes/console.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
19 | })->purpose('Display an inspiring quote');
20 |
--------------------------------------------------------------------------------
/back/routes/web.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
18 |
19 | return $app;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/back/tests/Feature/ExampleTest.php:
--------------------------------------------------------------------------------
1 | get('/');
16 |
17 | $response->assertStatus(200);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/back/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/back/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import laravel from 'laravel-vite-plugin';
3 |
4 | export default defineConfig({
5 | plugins: [
6 | laravel({
7 | input: ['resources/css/app.css', 'resources/js/app.js'],
8 | refresh: true,
9 | }),
10 | ],
11 | });
12 |
--------------------------------------------------------------------------------
/docker/conf/supervisor/cron.ini:
--------------------------------------------------------------------------------
1 | [program:cron]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=crond -f
4 | autostart=true
5 | autorestart=true
6 | user=root
7 | numprocs=1
8 | redirect_stderr=true
9 | stdout_logfile=/dev/stdout
10 | stdout_logfile_maxbytes=0
11 | stopwaitsecs=10
--------------------------------------------------------------------------------
/docker/conf/supervisor/nginx.ini:
--------------------------------------------------------------------------------
1 | [program:nginx]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=/usr/sbin/nginx -g "daemon off;"
4 | autostart=true
5 | autorestart=true
6 | user=root
7 | redirect_stderr=true
8 | stdout_logfile=/dev/stdout
9 | stdout_logfile_maxbytes=0
10 | stopwaitsecs=10
--------------------------------------------------------------------------------
/docker/conf/supervisor/node.ini:
--------------------------------------------------------------------------------
1 | [program:node]
2 | process_name=%(program_name)s_%(process_num)02d
3 | directory=/var/www/html/front
4 | command=npm run prod
5 | autostart=true
6 | autorestart=true
7 | redirect_stderr=true
8 | stdout_logfile=/dev/stdout
9 | stdout_logfile_maxbytes=0
10 | stopwaitsecs=10
--------------------------------------------------------------------------------
/docker/conf/supervisor/php-fpm.ini:
--------------------------------------------------------------------------------
1 | [program:php-fpm]
2 | process_name=%(program_name)s_%(process_num)02d
3 | command=/usr/sbin/php-fpm82 --nodaemonize
4 | autostart=true
5 | autorestart=true
6 | user=root
7 | redirect_stderr=true
8 | stdout_logfile=/dev/stdout
9 | stdout_logfile_maxbytes=0
10 | stopwaitsecs=10
--------------------------------------------------------------------------------
/docker/conf/supervisor/supervisord.conf:
--------------------------------------------------------------------------------
1 | [unix_http_server]
2 | file=/run/supervisord.sock ; the path to the socket file
3 | [supervisord]
4 | logfile=/var/log/supervisord.log ; main log file; default $CWD/supervisord.log
5 | pidfile=/run/supervisord.pid ; supervisord pidfile; default supervisord.pid
6 | nodaemon=true ; start in foreground if true; default false
7 | user=root ; setuid to this UNIX account at startup; recommended if root
8 | [rpcinterface:supervisor]
9 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
10 | [supervisorctl]
11 | serverurl=unix:///run/supervisord.sock ; use a unix:// URL for a unix socket
12 | [include]
13 | files = /etc/supervisor.d/*.ini
--------------------------------------------------------------------------------
/docs/attribution.md:
--------------------------------------------------------------------------------
1 | ## Credits
2 |
3 | - Developed by Mihai Cioraneanu
4 | - Using [Laravel](https://laravel.com/) and [Nuxt](https://nuxt.com/)
5 | - Consuming the [Firefly III](https://www.firefly-iii.org) REST API
6 | - With a UI theme based on [Vant](https://vant-ui.github.io)
7 | - Exchange rate by [Exchange Rate API](https://www.exchangerate-api.com)
8 |
9 |
10 | - IconPacks: [Tablr Icons](https://tabler.io/icons)
11 | - IconPacks: [Fluent UI System Icons](https://github.com/microsoft/fluentui)
12 | - IconPacks: [Circle Avatar Vectors by Laura Reen](https://www.svgrepo.com/author/Laura%20Reen)
13 | - IconPacks: [SVG Repo](https://www.svgrepo.com/)
14 | - Illustrations: [unDraw](https://undraw.co)
15 |
16 | If you enjoy Firefly-Pico please ⭐️ it on [GitHub](https://github.com/cioraneanu/firefly-pico).
--------------------------------------------------------------------------------
/docs/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/docs/images/architecture.png
--------------------------------------------------------------------------------
/docs/images/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/docs/images/demo.gif
--------------------------------------------------------------------------------
/docs/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/docs/images/logo.png
--------------------------------------------------------------------------------
/docs/images/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/docs/images/logo2.png
--------------------------------------------------------------------------------
/docs/images/presentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/docs/images/presentation.png
--------------------------------------------------------------------------------
/front/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log*
3 | .nuxt
4 | .nitro
5 | .cache
6 | .output
7 | .env
8 | dist
9 | .idea
10 |
--------------------------------------------------------------------------------
/front/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 | strict-peer-dependencies=false
3 |
--------------------------------------------------------------------------------
/front/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "semi": false,
4 | "bracketSpacing": true,
5 | "arrowParens": "always",
6 | "trailingComma": "all",
7 | "tabWidth": 2,
8 | "printWidth": 200,
9 | "endOfLine": "lf",
10 | "vueIndentScriptAndStyle": false
11 | }
12 |
--------------------------------------------------------------------------------
/front/README.md:
--------------------------------------------------------------------------------
1 | ## Structure
2 |
--------------------------------------------------------------------------------
/front/assets/icons/avatar/statistics-graph-svgrepo-com.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
10 |
11 |
--------------------------------------------------------------------------------
/front/assets/icons/avatar/wallet-svgrepo-com.svg:
--------------------------------------------------------------------------------
1 |
2 | 70 Basic icons by Xicons.co
--------------------------------------------------------------------------------
/front/assets/icons/custom/exchange.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/adhesive-plaster-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/airbuds-case.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/alarm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/archive-up-minimlistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/atom.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bag-4.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bag-5.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bag.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/balloon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/banknote.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bar-chair.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/basketball.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/battery-charge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bedside-table-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bedside-table-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bedside-table-4.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bonfire.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/bowling.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/box.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/calendar-add.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/card-recive.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/card-search.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/card-send.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/card-transfer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/card.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/cardholder.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/cash-out.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/chair.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/chandelier.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/clapperboard-text.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/closet-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/cloud-bolt-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/code.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/colour-tuneing.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/cup.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/database.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/diagram-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/diskette.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/display.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/documents-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/dollar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/earth.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/end-call-rounded.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/euro.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/eye.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/fire.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/flag.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/flame.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/fridge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/ghost-smile.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/glasses.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/golf.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/gps.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/hanger-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/hanger.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/heart.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/history-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/home-angle-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/hourglass-line.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/incognito.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/iphone.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/ladle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/leaf.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/lock-keyhole.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/magnet.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/magnifer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/map-arrow-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/map-point-wave.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/medical-kit.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/men.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/microphone-large.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/microphone.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/money-bag.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/mouse.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/music-note-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/notification-unread-lines.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/oven-mitts.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/palette-round.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/paper-bin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/pill.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/planet-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/planet-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/presentation-graph.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/pulse-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/radio-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/scissors.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/sleeping.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/smart-speaker-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/smart-vacuum-cleaner.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/snowflake.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/sofa-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/sofa.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/speaker.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/square-academic-cap.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/stethoscope.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/stretching-round.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/suitcase-lines.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/suitcase.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/tag.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/target.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/temperature.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/tennis-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/tennis.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/test-tube-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/thermometer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/tornado-small.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/tv.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/user.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/washing-machine-minimalistic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/waterdrop.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/waterdrops.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/whisk.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/wineglass-triangle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/front/assets/icons/duo/women.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/front/assets/icons/flags/it.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/flags/ro.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/bike.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_24_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_bank_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_home_16_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_mosque_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_multiple_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/building_townhouse_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/chick.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/crown_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/desktop_sync_24_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/dishwasher_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/emoji_24_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/food_24_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/food_chicken_leg_16_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/food_pizza_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/glasses.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/home_garage_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/ice-cream.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/kid1.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/kid2.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/kid3.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/motorbike.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/pants.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/school.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/scooter.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/scooter2.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/shifts_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/shoe.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/stack_star_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/underwear.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/vehicle_bicycle_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/vehicle_car_profile_24_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/wallet_20_regular.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/front/assets/icons/fluent/wifi.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/front/components/charts/bar-chart-item-horizontal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ props.value }}
4 |
7 |
{{ props.label }}
8 |
9 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/front/components/charts/bar-chart-item-vertical.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ props.value }}
4 |
7 |
{{ props.label }}
8 |
9 |
10 |
11 |
22 |
--------------------------------------------------------------------------------
/front/components/dashboard/dashboard-calendar/dashboard-calendar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/front/components/dashboard/dashboard-summary/dashboard-summary-card.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
{{ title }}
9 |
{{ subtitle }}
10 |
11 |
12 |
13 |
14 |
26 |
--------------------------------------------------------------------------------
/front/components/general/empty-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
The list is empty. Add some entries with the top-right button.
6 |
7 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/front/components/list-items/app-list-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
32 |
--------------------------------------------------------------------------------
/front/components/select/budget/budget-period-select.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/front/components/select/budget/budget-type-select.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/front/components/select/date-format-select.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
--------------------------------------------------------------------------------
/front/components/select/page-select.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
31 |
--------------------------------------------------------------------------------
/front/components/settings/app-config-stat.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ props.name }}
7 |
{{ props.value }}
8 |
9 |
10 |
11 |
12 |
19 |
--------------------------------------------------------------------------------
/front/components/transaction/transaction-split-badge.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ $t('transaction.split_transaction')}}
5 |
6 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/front/components/transaction/transaction-type-dot.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
--------------------------------------------------------------------------------
/front/components/transaction/transaction-type-tabs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t(item.t) }}
5 |
6 |
7 |
8 |
9 |
10 |
29 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-checkbox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ props.label }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
26 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-chip.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ title }}
4 |
{{ subtitle }}
5 |
6 |
7 |
8 |
24 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-field-link.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
31 |
32 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-loading.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ profileStore.loadingMessage }}
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-select-option.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ props.text }}
5 |
6 |
7 |
8 |
9 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/front/components/ui-kit/app-tab-bar-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ name }}
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/front/components/ui-kit/theme/app-button-form-delete.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('delete') }}
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/front/components/ui-kit/theme/app-button-list-add.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('new') }}
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/front/components/ui-kit/theme/app-card-info.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/front/components/ui-kit/theme/app-list-search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/front/composables/useFormAttributes.js:
--------------------------------------------------------------------------------
1 | export function useFormAttributes(attributes, customAttributes = {}) {
2 | const dynamicAttrs = computed(() => {
3 | let defaultAttributes = {
4 | 'label-align': 'top',
5 | 'placeholder': attributes?.label
6 | }
7 | return { ...defaultAttributes, ...attributes, ...customAttributes }
8 | })
9 |
10 | return {
11 | dynamicAttrs,
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/front/constants/Constants.js:
--------------------------------------------------------------------------------
1 | export const REPO_URL = 'https://github.com/cioraneanu/firefly-pico/tags'
2 |
--------------------------------------------------------------------------------
/front/constants/DashboardConstants.js:
--------------------------------------------------------------------------------
1 | export const dashboardCard = {
2 | calendar: { t: 'calendar', code: 'calendar', isVisible: true },
3 | accounts: { t: 'settings.dashboard.cards.accounts_summary', code: 'accounts', isVisible: true },
4 | expensesLastWeek: { t: 'settings.dashboard.cards.expenses_this_week', code: 'expensesLastWeek', isVisible: true },
5 | transactionsSummary: { t: 'settings.dashboard.cards.transactions_summary', code: 'transactionSummary', isVisible: true },
6 | budgets: { t: 'budgets', code: 'budgets', isVisible: true },
7 | expensesByTag: { t: 'settings.dashboard.cards.expenses_by_tag', code: 'expensesByTag', isVisible: true },
8 | expensesByCategory: { t: 'settings.dashboard.cards.expenses_by_category', code: 'expensesByCategory', isVisible: true },
9 | todoTransactions: { t: 'settings.dashboard.cards.todo_transactions', code: 'todoTransactions', isVisible: true },
10 | }
11 |
12 | export const dashboardCardList = Object.values(dashboardCard)
13 |
--------------------------------------------------------------------------------
/front/constants/LanguageConstants.js:
--------------------------------------------------------------------------------
1 | export const LANGUAGE_ENGLISH = 'en-US'
2 | export const LANGUAGE_ROMANIAN = 'ro-RO'
3 | export const LANGUAGE_FRENCH = 'fr-FR'
4 |
5 | export const OPTION_ENGLISH = { code: LANGUAGE_ENGLISH, name: 'English', flag: 'en' }
6 | export const OPTION_ROMANIAN = { code: LANGUAGE_ROMANIAN, name: 'Romanian', flag: 'ro' }
7 | export const OPTION_FRENCH = { code: LANGUAGE_FRENCH, name: 'French', flag: 'fr' }
8 |
9 | export const OPTIONS_LIST = [OPTION_ENGLISH, OPTION_ROMANIAN, OPTION_FRENCH]
10 |
--------------------------------------------------------------------------------
/front/constants/TutorialConstants.js:
--------------------------------------------------------------------------------
1 | export const TUTORIAL_CONSTANTS = {
2 |
3 | todoTag: {
4 | title: 'Todo Tag',
5 | body: `
6 |
One of your Tags can be marked as your "todo". This is useful for knowing which transactions require some later edits and you easily keep an eye on them straight from the dashboard
7 | Ex. If you're buying multiple items with the intent to keep only some of them and return the rest.
8 | There can only be one "todo" tag so setting a second one will clear it from the first one.
9 | `,
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/front/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import withNuxt from './.nuxt/eslint.config.mjs'
3 |
4 | export default withNuxt({
5 | // rules: {
6 | // 'no-console': 'off', // allow console.log in TypeScript files
7 | // },
8 | })
9 |
--------------------------------------------------------------------------------
/front/global.d.ts:
--------------------------------------------------------------------------------
1 | interface Array {
2 | uniqBy(field): T[];
3 | }
--------------------------------------------------------------------------------
/front/i18n/i18n.config.js:
--------------------------------------------------------------------------------
1 | export default defineI18nConfig(() => ({
2 | legacy: false,
3 | locale: 'en',
4 | fallbackLocale: 'en',
5 | fallbackWarn: true,
6 | missingWarn: true,
7 | }))
8 |
9 |
--------------------------------------------------------------------------------
/front/i18n/index.js:
--------------------------------------------------------------------------------
1 | // import { flags } from '~/constants/SvgConstants.js'
2 |
3 | export const languageCode = {
4 | english: 'en',
5 | romanian: 'ro',
6 | chinese: 'zh-CN',
7 | italian: 'it'
8 | }
9 |
10 | export const supportedLanguages = [
11 | {
12 | code: languageCode.english,
13 | file: 'en.json',
14 | displayName: 'English',
15 | icon: 'svgo-flags-en',
16 | },
17 | {
18 | code: languageCode.romanian,
19 | file: 'ro.json',
20 | displayName: 'Română',
21 | icon: 'svgo-flags-ro',
22 | },
23 | {
24 | code: languageCode.chinese,
25 | file: 'zh-CN.json',
26 | displayName: '简体中文',
27 | icon: 'svgo-flags-cn',
28 | },
29 | {
30 | code: languageCode.italian,
31 | file: 'it.json',
32 | displayName: 'Italiano',
33 | icon: 'svgo-flags-it',
34 | },
35 | ]
36 |
--------------------------------------------------------------------------------
/front/layouts/default.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | import { ref } from 'vue';
10 |
11 |
22 |
--------------------------------------------------------------------------------
/front/layouts/empty.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Empty layout
4 |
5 |
6 |
7 |
8 |
9 | import { ref } from 'vue';
10 |
11 |
12 |
--------------------------------------------------------------------------------
/front/models/BaseModel.js:
--------------------------------------------------------------------------------
1 | import _, { get } from 'lodash'
2 |
3 | export default class BaseModel {
4 | constructor() {}
5 |
6 | getEmpty() {
7 | throw 'Implement me'
8 | }
9 |
10 | getFake(id) {
11 | throw 'Implement me'
12 | }
13 |
14 | getFakeList() {
15 | let list = []
16 | for (let i = 1; i <= 50; i++) {
17 | list.push(this.getFake(i))
18 | }
19 | return {
20 | data: list,
21 | }
22 | }
23 |
24 | static getIcon(item) {
25 | return get(item, 'attributes.icon.icon')
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/front/models/Profile.js:
--------------------------------------------------------------------------------
1 | import BaseModel from '~/models/BaseModel'
2 | import ProfileTransformer from '~/transformers/ProfileTransformer'
3 | import ProfileRepository from '~/repository/ProfileRepository'
4 |
5 | class Profile extends BaseModel {
6 | getTransformer() {
7 | return ProfileTransformer
8 | }
9 |
10 | getRepository() {
11 | return new ProfileRepository()
12 | }
13 |
14 | getEmpty() {
15 | return {}
16 | }
17 |
18 | // ------------
19 |
20 | getFake() {
21 | return {}
22 | }
23 | }
24 |
25 | export default Profile
26 |
--------------------------------------------------------------------------------
/front/modules/register-components.js:
--------------------------------------------------------------------------------
1 | import { addComponent, defineNuxtModule } from '@nuxt/kit'
2 | // import icons from '../constants/TablerIconConstants'
3 | // import {IconPhone} from '@tabler/icons-vue'
4 |
5 | export default defineNuxtModule({
6 | setup() {
7 | // addImports({ name: 'IconAngle', as: 'IconAngle', from: "@tabler/icons-vue" })
8 | // addComponent({
9 | // name: 'MyTest',
10 | // export: 'IconAngle',
11 | // filePath: '@tabler/icons-vue',
12 | // global: false
13 | // })
14 | // addComponent({
15 | // name: 'IconAnalyze',
16 | // export: 'IconAnalyze',
17 | // filePath: '@tabler/icons-vue',
18 | // global: true
19 | // })
20 | // for (let icon of Object.values(icons)) {
21 | //
22 | // addComponent({
23 | // name: icon,
24 | // export: icon,
25 | // filePath: '@tabler/icons-vue',
26 | // // global: true
27 | // })
28 | // }
29 | },
30 | })
31 |
--------------------------------------------------------------------------------
/front/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
26 |
--------------------------------------------------------------------------------
/front/pages/mihai.vue:
--------------------------------------------------------------------------------
1 |
2 | Page Mihai
3 |
4 |
5 |
12 |
--------------------------------------------------------------------------------
/front/plugins/array-extension.js:
--------------------------------------------------------------------------------
1 | export default defineNuxtPlugin((nuxtApp) => {
2 | Array.prototype.uniqBy = function (field) {
3 | return [...new Map(this.map((item) => [item[field], item])).values()]
4 | }
5 | })
6 |
--------------------------------------------------------------------------------
/front/plugins/plugin-date-fns.js:
--------------------------------------------------------------------------------
1 | import { setDefaultOptions } from 'date-fns'
2 | import { ro, enUS, zhCN, it } from 'date-fns/locale'
3 | import { languageCode } from '~/i18n/index.js'
4 |
5 | export default defineNuxtPlugin((nuxtApp) => {
6 | watch(
7 | () => useProfileStore().weekStartsOn,
8 | (newValue) => {
9 | setDefaultOptions({ weekStartsOn: newValue })
10 | },
11 | { immediate: true },
12 | )
13 |
14 | watch(
15 | () => useProfileStore().language,
16 | (newValue) => {
17 | const dateFnsLocaleDictionary = {
18 | [languageCode.english]: enUS,
19 | [languageCode.romanian]: ro,
20 | [languageCode.chinese]: zhCN,
21 | [languageCode.italian]: it,
22 | }
23 | let dateFnsLocale = dateFnsLocaleDictionary[newValue] || enUS
24 |
25 | setDefaultOptions({ locale: dateFnsLocale })
26 | },
27 | { immediate: true },
28 | )
29 | })
30 |
--------------------------------------------------------------------------------
/front/plugins/plugin-i18n.js:
--------------------------------------------------------------------------------
1 | import { useI18n } from '#imports'
2 | import { useNuxtApp } from '#app'
3 |
4 | export default defineNuxtPlugin((nuxtApp) => {
5 | // const { setLocale } = useI18n()
6 |
7 | watch(
8 | () => useProfileStore().language,
9 | (newValue) => {
10 | nuxtApp.$i18n.setLocale(newValue)
11 | },
12 | { immediate: true },
13 | )
14 | })
15 |
16 |
17 | // Useful if we need translations in plain JS files (no components or composables)
18 | export const translate = (key) => useNuxtApp()?.$i18n?.t(key)
19 |
--------------------------------------------------------------------------------
/front/plugins/plugin-vant.js:
--------------------------------------------------------------------------------
1 | // Vant theme related
2 | import '@vant/touch-emulator'
3 |
4 | // Vant locale related
5 | import { Locale } from 'vant'
6 | import enUS from 'vant/es/locale/lang/en-US'
7 | import ro from 'vant/es/locale/lang/ro-RO'
8 | import zhCN from 'vant/es/locale/lang/zh-CN'
9 | import italian from 'vant/es/locale/lang/it-IT'
10 |
11 | import { languageCode } from '~/i18n/index.js'
12 |
13 | export default defineNuxtPlugin((nuxtApp) => {
14 | watch(
15 | () => useProfileStore().language,
16 | (newValue) => {
17 | const localeDictionary = {
18 | [languageCode.english]: enUS,
19 | [languageCode.romanian]: ro,
20 | [languageCode.chinese]: zhCN,
21 | [languageCode.italian]: italian,
22 | }
23 | let locale = localeDictionary[newValue] || enUS
24 | Locale.use(newValue, locale)
25 | },
26 | { immediate: true },
27 | )
28 | })
29 |
--------------------------------------------------------------------------------
/front/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/front/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/front/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/front/public/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/front/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/favicon-16x16.png
--------------------------------------------------------------------------------
/front/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/favicon-32x32.png
--------------------------------------------------------------------------------
/front/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/favicon.ico
--------------------------------------------------------------------------------
/front/public/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cioraneanu/firefly-pico/3f97e0b24ecf642cb4835bee62a01c062e36db0c/front/public/mstile-150x150.png
--------------------------------------------------------------------------------
/front/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/front/repository/AccountRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 | import _ from 'lodash'
4 | import { useProfileStore } from '~/stores/profileStore'
5 | import { useDataStore } from '~/stores/dataStore'
6 |
7 | class AccountRepository extends BaseRepository {
8 | constructor() {
9 | super('api/accounts')
10 | }
11 | }
12 |
13 | export default AccountRepository
14 |
--------------------------------------------------------------------------------
/front/repository/BudgetRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 | import _ from 'lodash'
4 |
5 | export default class BudgetRepository extends BaseRepository {
6 | constructor() {
7 | super(`api/budgets`)
8 | }
9 |
10 | async getBudgetLimits() {
11 | const appStore = useAppStore()
12 | let response = await axios.get(`${appStore.picoBackendURL}/api/budget-limits`)
13 | return _.get(response, 'data', {})
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/front/repository/CategoryRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 |
3 | class CategoryRepository extends BaseRepository {
4 | constructor() {
5 | super(`api/categories`)
6 | }
7 | }
8 |
9 | export default CategoryRepository
10 |
--------------------------------------------------------------------------------
/front/repository/CurrencyRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 | import _, { get } from 'lodash'
4 |
5 | class CurrencyRepository extends BaseRepository {
6 | constructor() {
7 | super(`api/currencies`)
8 | }
9 |
10 | async update(id, data) {
11 | return await axios.put(`${this.getUrl()}/${data.code}`, data)
12 | }
13 |
14 | async delete(id) {
15 | let dataStore = useDataStore()
16 | let currencyCode = dataStore.currencyDictionary[id]?.attributes?.code
17 | return await axios.delete(`${this.getUrl()}/${currencyCode}`)
18 | }
19 |
20 | async getCurrencyExchange() {
21 | const appStore = useAppStore()
22 | const url = `${appStore.picoBackendURL}/api/currencies/exchange`
23 | let response = await axios.get(url)
24 | return _.get(response, 'data', {})
25 | }
26 | }
27 |
28 | export default CurrencyRepository
29 |
--------------------------------------------------------------------------------
/front/repository/InfoRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 |
4 | export default class InfoRepository extends BaseRepository {
5 | constructor() {
6 | super('api/latest-version')
7 | }
8 |
9 | async getLatestVersion() {
10 | return await axios.get(`${this.getUrl()}`)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/front/repository/ProfileRepository.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import BaseRepository from '~/repository/BaseRepository'
3 | import _ from 'lodash'
4 |
5 | class ProfileRepository extends BaseRepository {
6 | constructor() {
7 | super('api/profile')
8 | }
9 |
10 | async getProfile() {
11 | let result = await axios.get(`${this.getUrl()}`)
12 | return _.get(result, 'data', {})
13 | }
14 |
15 | async writeProfile(data) {
16 | let result = await axios.put(`${this.getUrl()}`, data)
17 | return result
18 | }
19 | }
20 |
21 | export default ProfileRepository
22 |
--------------------------------------------------------------------------------
/front/repository/TagRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 |
3 | class CategoryRepository extends BaseRepository {
4 | constructor() {
5 | super('api/tags')
6 | }
7 | }
8 |
9 | export default CategoryRepository
10 |
--------------------------------------------------------------------------------
/front/repository/TransactionRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 | import _ from 'lodash'
4 |
5 | class TransactionRepository extends BaseRepository {
6 | constructor() {
7 | super(`api/transactions`)
8 | this.searchTransaction = this.searchTransaction.bind(this)
9 | }
10 |
11 |
12 | async searchTransaction({ filters = [], page = 1, pageSize = 50 } = {}) {
13 | const appStore = useAppStore()
14 | const url = `${appStore.picoBackendURL}/api/search/transactions`
15 | let searchUrl = this.getUrlForRequest({ filters, page, pageSize, url })
16 | let response = await axios.get(searchUrl)
17 | return _.get(response, 'data', {})
18 | }
19 | }
20 |
21 | export default TransactionRepository
22 |
--------------------------------------------------------------------------------
/front/repository/TransactionTemplateRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 | import _ from 'lodash'
4 |
5 | class TransactionTemplateRepository extends BaseRepository {
6 | constructor() {
7 | super(`api/transaction-templates`)
8 | }
9 |
10 | // async getOne (id) {
11 | // // const baseURL = this.getBaseUrl()
12 | // let result = await axios.get(`${this.endpoint}/${id}`)
13 | // return _.get(result, 'data', {})
14 | // }
15 | //
16 | // async getAll ({ filters = [], page = 1, pageSize = 10 } = {}) {
17 | // let url = this.getUrlForRequest({ filters, page, pageSize })
18 | // let response = await axios.get(url)
19 | // return _.get(response, 'data', {})
20 | // }
21 | }
22 |
23 | export default TransactionTemplateRepository
24 |
--------------------------------------------------------------------------------
/front/repository/UserRepository.js:
--------------------------------------------------------------------------------
1 | import BaseRepository from '~/repository/BaseRepository'
2 | import axios from 'axios'
3 |
4 | export default class UserRepository extends BaseRepository {
5 | constructor() {
6 | super('api/user')
7 | }
8 |
9 | async getUser() {
10 | return await axios.get(`${this.getUrl()}`)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/front/transformers/CurrencyTransformer.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | import DateUtils from '~/utils/DateUtils'
3 | import Account from '~/models/Account'
4 | import Utils from '~/utils/Utils'
5 | import ApiTransformer from '~/transformers/ApiTransformer'
6 |
7 | export default class CurrencyTransformer extends ApiTransformer {
8 | static transformFromApi(item) {
9 | if (!item) {
10 | return null
11 | }
12 | return item
13 | }
14 |
15 | static transformToApi(item) {
16 | if (!item) {
17 | return null
18 | }
19 |
20 | let data = _.get(item, 'attributes')
21 | let result = _.pick(data, ['name', 'code', 'symbol', 'decimal_places', 'enabled', 'default'])
22 |
23 | return result
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/front/transformers/ProfileTransformer.js:
--------------------------------------------------------------------------------
1 | import ApiTransformer from '~/transformers/ApiTransformer'
2 |
3 | export default class ProfileTransformer extends ApiTransformer {
4 | static transformFromApi(item) {
5 | if (!item) {
6 | return null
7 | }
8 |
9 | return item.settings
10 | }
11 |
12 | static transformToApi(item) {
13 | if (!item) {
14 | return null
15 | }
16 |
17 | return {
18 | settings: item,
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/front/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // https://nuxt.com/docs/guide/concepts/typescript
3 | "extends": "./.nuxt/tsconfig.json"
4 | }
5 |
--------------------------------------------------------------------------------
/front/utils/LanguageUtils.js:
--------------------------------------------------------------------------------
1 | export default class LanguageUtils {
2 | static removeAccents(text) {
3 | if (!text) {
4 | return ''
5 | }
6 | return text
7 | .normalize('NFD')
8 | .replace(/[\u0300-\u036f]/g, '')
9 | }
10 |
11 | static removeAccentsAndLowerCase(text) {
12 | text = LanguageUtils.removeAccents(text)
13 | text = LanguageUtils.lowercase(text)
14 | return text
15 | }
16 |
17 | static lowercase(text) {
18 | if (!text) {
19 | return ''
20 | }
21 | return text.toLowerCase()
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/front/utils/NumberUtils.js:
--------------------------------------------------------------------------------
1 | export const NUMBER_FORMAT = {
2 | eu: { name: '1234.56 -> 1.234,56', code: 'de-DE' },
3 | international: { name: '1234.56 -> 1,234.56', code: 'en-EN' },
4 | }
5 |
6 | export const formatNumber = (value, digits) => {
7 | const profileStore = useProfileStore()
8 | let numberFormatCode = profileStore.numberFormat.code ?? NUMBER_FORMAT.eu.code
9 |
10 | return new Intl.NumberFormat(numberFormatCode, {
11 | minimumFractionDigits: digits,
12 | maximumFractionDigits: digits,
13 | }).format(value)
14 | }
15 |
16 | export const formatNumberForDashboard = (value) => {
17 | const profileStore = useProfileStore()
18 | if (!profileStore.dashboard.showAccountAmounts) {
19 | return '******'
20 | }
21 | let digits = profileStore.dashboard.showDecimal ? 2 : 0
22 | return formatNumber(value, digits)
23 | }
24 |
--------------------------------------------------------------------------------
/front/utils/ResponseUtils.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 | const STATUS_CODE_SUCCESS = 200
3 | const STATUS_CODE_SUCCESS_DELETE = 204
4 |
5 | export default class ResponseUtils {
6 | static isSuccess(response) {
7 | const responseStatus = _.get(response, 'status', ' - ')
8 | const successCodesList = [STATUS_CODE_SUCCESS, STATUS_CODE_SUCCESS_DELETE]
9 | return successCodesList.includes(responseStatus)
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/front/utils/SettingUtils.js:
--------------------------------------------------------------------------------
1 | import { set, get } from 'lodash'
2 | import { watch } from 'vue'
3 |
4 | export function saveSettingsToStore(settingsList) {
5 | for (let setting of settingsList) {
6 | let { store, path, ref } = setting
7 | set(store, path, ref.value)
8 | }
9 | }
10 |
11 | export function saveSettingsToLocal(settingsList) {
12 | for (let setting of settingsList) {
13 | let { store, path, ref } = setting
14 | ref.value = get(store, path)
15 | }
16 | }
17 |
18 | export function watchSettingsStore(settingsList) {
19 | let watchList = () =>
20 | settingsList.reduce((result, setting) => {
21 | let { store, path, ref } = setting
22 | result = [...result, get(store, path)]
23 | return result
24 | }, [])
25 |
26 | watch(watchList, () => saveSettingsToLocal(settingsList), { immediate: true })
27 | }
28 |
--------------------------------------------------------------------------------
/front/utils/Utils.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash'
2 |
3 | export default class UIUtils {
4 | static getGUID() {
5 | return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16))
6 | }
7 |
8 | static updateListWithNewItems(list, newItems) {
9 | newItems = _.isArray(newItems) ? newItems : [newItems]
10 | let newItemIds = newItems.map((item) => item.id)
11 | let initialListFiltered = list.filter((item) => !newItemIds.includes(item.id))
12 | return [...newItems, ...initialListFiltered]
13 | }
14 |
15 | static stringToData(item, path, list) {
16 | const type = _.get(item, path)
17 | const convertedType = list.find((accountType) => accountType.code === type)
18 | _.set(item, path, convertedType)
19 | }
20 | }
21 |
22 | export function ellipsizeText(text = '', maxLength = 100) {
23 | return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text
24 | }
25 |
--------------------------------------------------------------------------------
/front/utils/ValidationUtils.js:
--------------------------------------------------------------------------------
1 | export const rule = {
2 |
3 | // TODO: Interpolate fieldName into the message. The field name should be translated as well. Ex. The "description" field is required.
4 | required: (fieldName) => {
5 | const { t } = useI18n()
6 | return { required: true, message: t('validation.required') }
7 | },
8 |
9 | }
10 |
--------------------------------------------------------------------------------