diff --git a/Gemfile b/Gemfile
index 655e978..a5b2d26 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,10 +10,10 @@ gem "rails", "~> 7.2"
gem "sprockets-rails"
# Use postgresql as the database for Active Record
-gem "pg", "~> 1.1"
+gem "pg"
# Use the Puma web server [https://github.com/puma/puma]
-gem "puma", "~> 5.0"
+gem "puma"
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]
gem "importmap-rails"
@@ -28,7 +28,7 @@ gem "stimulus-rails"
gem "jbuilder"
# Use Redis adapter to run Action Cable in production
-gem "redis", "~> 4.0"
+gem "redis"
# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"
@@ -82,4 +82,4 @@ group :development do
gem "annotate"
end
-gem "tailwindcss-rails", "~> 2.0"
+gem "tailwindcss-rails"
diff --git a/Gemfile.lock b/Gemfile.lock
index 385ca7a..59f765a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -72,8 +72,8 @@ GEM
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
- addressable (2.8.1)
- public_suffix (>= 2.0.2, < 6.0)
+ addressable (2.8.7)
+ public_suffix (>= 2.0.2, < 7.0)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
@@ -82,9 +82,9 @@ GEM
benchmark (0.3.0)
bigdecimal (3.1.8)
bindex (0.8.1)
- bootsnap (1.16.0)
+ bootsnap (1.18.4)
msgpack (~> 1.2)
- builder (3.2.4)
+ builder (3.3.0)
byebug (11.1.3)
capybara (3.40.0)
addressable
@@ -95,6 +95,8 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
+ childprocess (5.1.0)
+ logger (~> 1.5)
coderay (1.1.3)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
@@ -103,19 +105,19 @@ GEM
activerecord (>= 6.1)
railties (>= 6.1)
date (3.4.0)
- diff-lcs (1.5.0)
- docile (1.4.0)
+ diff-lcs (1.5.1)
+ docile (1.4.1)
drb (2.2.1)
- erubi (1.12.0)
- factory_bot (6.2.1)
+ erubi (1.13.0)
+ factory_bot (6.5.0)
activesupport (>= 5.0.0)
- factory_bot_rails (6.2.0)
- factory_bot (~> 6.2.0)
+ factory_bot_rails (6.4.4)
+ factory_bot (~> 6.5)
railties (>= 5.0.0)
faker (3.5.1)
i18n (>= 1.8.11, < 2)
- globalid (1.1.0)
- activesupport (>= 5.0)
+ globalid (1.2.1)
+ activesupport (>= 6.1)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
importmap-rails (2.0.3)
@@ -130,11 +132,12 @@ GEM
jbuilder (2.13.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
- json (2.6.3)
+ json (2.7.6)
language_server-protocol (3.17.0.3)
- launchy (2.5.2)
+ launchy (3.0.1)
addressable (~> 2.8)
- lint_roller (1.0.0)
+ childprocess (~> 5.0)
+ lint_roller (1.1.0)
logger (1.6.1)
loofah (2.23.1)
crass (~> 1.0.2)
@@ -146,20 +149,20 @@ GEM
net-smtp
marcel (1.0.4)
matrix (0.4.2)
- method_source (1.0.0)
- mini_mime (1.1.2)
- minitest (5.18.0)
- monetize (1.12.0)
+ method_source (1.1.0)
+ mini_mime (1.1.5)
+ minitest (5.25.1)
+ monetize (1.13.0)
money (~> 6.12)
- money (6.16.0)
+ money (6.19.0)
i18n (>= 0.6.4, <= 2)
money-rails (1.15.0)
activesupport (>= 3.0)
monetize (~> 1.9)
money (~> 6.13)
railties (>= 3.0)
- msgpack (1.7.1)
- net-http (0.3.2)
+ msgpack (1.7.3)
+ net-http (0.4.1)
uri
net-imap (0.5.0)
date
@@ -170,7 +173,7 @@ GEM
timeout
net-smtp (0.5.0)
net-protocol
- nio4r (2.5.9)
+ nio4r (2.7.4)
nokogiri (1.16.7-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.7-x86_64-linux)
@@ -178,27 +181,28 @@ GEM
orderly (0.1.1)
capybara (>= 1.1)
rspec (>= 2.14)
- parallel (1.23.0)
- parser (3.2.2.1)
+ parallel (1.26.3)
+ parser (3.3.6.0)
ast (~> 2.4.1)
- pg (1.5.3)
+ racc
+ pg (1.5.9)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
- pry-rails (0.3.9)
- pry (>= 0.10.4)
+ pry-rails (0.3.11)
+ pry (>= 0.13.0)
pry-rescue (1.6.0)
interception (>= 0.5)
pry (>= 0.12.0)
psych (5.1.2)
stringio
- public_suffix (5.0.1)
- puma (5.6.5)
+ public_suffix (6.0.1)
+ puma (6.4.3)
nio4r (~> 2.0)
- racc (1.6.2)
+ racc (1.8.1)
rack (3.1.8)
rack-session (2.0.0)
rack (>= 3.0.0)
@@ -236,50 +240,52 @@ GEM
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
- rake (13.0.6)
+ rake (13.2.1)
rdoc (6.7.0)
psych (>= 4.0.0)
- redis (4.8.1)
- regexp_parser (2.6.2)
+ redis (5.3.0)
+ redis-client (>= 0.22.0)
+ redis-client (0.22.2)
+ connection_pool
+ regexp_parser (2.9.2)
reline (0.5.10)
io-console (~> 0.5)
- rexml (3.2.5)
- rspec (3.12.0)
- rspec-core (~> 3.12.0)
- rspec-expectations (~> 3.12.0)
- rspec-mocks (~> 3.12.0)
- rspec-core (3.12.3)
- rspec-support (~> 3.12.0)
- rspec-expectations (3.12.2)
+ rspec (3.13.0)
+ rspec-core (~> 3.13.0)
+ rspec-expectations (~> 3.13.0)
+ rspec-mocks (~> 3.13.0)
+ rspec-core (3.13.2)
+ rspec-support (~> 3.13.0)
+ rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.12.0)
- rspec-mocks (3.12.3)
+ rspec-support (~> 3.13.0)
+ rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.12.0)
- rspec-rails (6.1.1)
- actionpack (>= 6.1)
- activesupport (>= 6.1)
- railties (>= 6.1)
- rspec-core (~> 3.12)
- rspec-expectations (~> 3.12)
- rspec-mocks (~> 3.12)
- rspec-support (~> 3.12)
- rspec-support (3.12.0)
- rubocop (1.50.2)
+ rspec-support (~> 3.13.0)
+ rspec-rails (7.0.1)
+ actionpack (>= 7.0)
+ activesupport (>= 7.0)
+ railties (>= 7.0)
+ rspec-core (~> 3.13)
+ rspec-expectations (~> 3.13)
+ rspec-mocks (~> 3.13)
+ rspec-support (~> 3.13)
+ rspec-support (3.13.1)
+ rubocop (1.66.1)
json (~> 2.3)
+ language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
- parser (>= 3.2.0.0)
+ parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
- regexp_parser (>= 1.8, < 3.0)
- rexml (>= 3.2.5, < 4.0)
- rubocop-ast (>= 1.28.0, < 2.0)
+ regexp_parser (>= 2.4, < 3.0)
+ rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
- rubocop-ast (1.28.1)
- parser (>= 3.2.1.0)
- rubocop-performance (1.16.0)
- rubocop (>= 1.7.0, < 2.0)
- rubocop-ast (>= 0.4.0)
+ rubocop-ast (1.34.0)
+ parser (>= 3.3.1.0)
+ rubocop-performance (1.22.1)
+ rubocop (>= 1.48.1, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (1.13.0)
securerandom (0.3.1)
shoulda-matchers (6.4.0)
@@ -288,7 +294,7 @@ GEM
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
- simplecov-html (0.12.3)
+ simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
sprockets (4.2.1)
concurrent-ruby (~> 1.0)
@@ -297,33 +303,35 @@ GEM
actionpack (>= 6.1)
activesupport (>= 6.1)
sprockets (>= 3.0.0)
- standard (1.28.2)
+ standard (1.41.1)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0)
- rubocop (~> 1.50.2)
+ rubocop (~> 1.66.0)
standard-custom (~> 1.0.0)
- standard-performance (~> 1.0.1)
- standard-custom (1.0.0)
- lint_roller (~> 1.0)
- standard-performance (1.0.1)
+ standard-performance (~> 1.5)
+ standard-custom (1.0.2)
lint_roller (~> 1.0)
- rubocop-performance (~> 1.16.0)
+ rubocop (~> 1.50)
+ standard-performance (1.5.0)
+ lint_roller (~> 1.1)
+ rubocop-performance (~> 1.22.0)
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.1)
- tailwindcss-rails (2.0.29-x86_64-darwin)
- railties (>= 6.0.0)
- tailwindcss-rails (2.0.29-x86_64-linux)
- railties (>= 6.0.0)
- thor (1.2.2)
+ tailwindcss-rails (3.0.0)
+ railties (>= 7.0.0)
+ tailwindcss-ruby
+ tailwindcss-ruby (3.4.14-x86_64-darwin)
+ tailwindcss-ruby (3.4.14-x86_64-linux)
+ thor (1.3.2)
timeout (0.4.1)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- unicode-display_width (2.4.2)
- uri (0.12.1)
+ unicode-display_width (2.6.0)
+ uri (0.13.1)
useragent (0.16.10)
web-console (4.2.1)
actionview (>= 6.0.0)
@@ -335,7 +343,7 @@ GEM
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.6.8)
+ zeitwerk (2.7.1)
PLATFORMS
x86_64-darwin-21
@@ -356,20 +364,20 @@ DEPENDENCIES
money-rails
net-http
orderly
- pg (~> 1.1)
+ pg
pry-byebug
pry-rails
pry-rescue
- puma (~> 5.0)
+ puma
rails (~> 7.2)
- redis (~> 4.0)
+ redis
rspec-rails
shoulda-matchers
simplecov
sprockets-rails
standard
stimulus-rails
- tailwindcss-rails (~> 2.0)
+ tailwindcss-rails
turbo-rails
tzinfo-data
web-console
diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css
index 3f7b012..5f1aa07 100644
--- a/app/assets/stylesheets/application.tailwind.css
+++ b/app/assets/stylesheets/application.tailwind.css
@@ -4,7 +4,7 @@
@layer components {
.btn-primary {
- @apply rounded-lg px-4 bg-purple-800 inline-block font-medium text-white;
+ @apply rounded-lg px-4 bg-primary-purple inline-block font-medium text-white;
}
.btn-danger {
@@ -41,6 +41,32 @@
border-radius: 0.5rem;
color: #2b2b2b;
}
+
+ .active-toolbar-tab {
+ background-color: white;
+ display: inline-block;
+ padding: 16px;
+ color: #5521B5;
+ border-top-left-radius: 0.5rem;
+ border-top-right-radius: 0.5rem;
+ }
+
+ .inactive-toolbar-tab {
+ display: inline-block;
+ padding: 16px;
+ border-top-left-radius: 0.5rem;
+ border-top-right-radius: 0.5rem;
+ }
+
+ .inactive-toolbar-tab:hover {
+ color: rgb(75 85 99);
+ background-color: rgb(249 250 251);
+ }
+
+ input[type="radio"].radio-button:checked {
+ background-color:#5521B5;
+ border:1px solid black;
+ }
}
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 189a80d..295b4ff 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -4,6 +4,10 @@ class DashboardController < ApplicationController
def index
build_dashboard_variables!
+ respond_to do |format|
+ format.turbo_stream
+ format.html
+ end
end
def switch_taxable_income
diff --git a/app/controllers/federal_tax_brackets_controller.rb b/app/controllers/federal_tax_brackets_controller.rb
index 88426d5..013b796 100644
--- a/app/controllers/federal_tax_brackets_controller.rb
+++ b/app/controllers/federal_tax_brackets_controller.rb
@@ -4,6 +4,10 @@ class FederalTaxBracketsController < ApplicationController
# GET /federal_tax_brackets or /federal_tax_brackets.json
def index
@federal_tax_brackets = FederalTaxBracket.order_by_range
+ respond_to do |format|
+ format.turbo_stream
+ format.html
+ end
end
# GET /federal_tax_brackets/1 or /federal_tax_brackets/1.json
diff --git a/app/javascript/application.js b/app/javascript/application.js
index 0d7b494..28313b0 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -1,3 +1,4 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
+import 'flowbite';
diff --git a/app/models/federal_tax_bracket.rb b/app/models/federal_tax_bracket.rb
index efb3fa7..3da6fde 100644
--- a/app/models/federal_tax_bracket.rb
+++ b/app/models/federal_tax_bracket.rb
@@ -31,7 +31,7 @@ class FederalTaxBracket < ApplicationRecord
monetize :cumulative_cents
def self.order_by_range
- all.order(:bottom_range_cents)
+ all.order(:federal_tax_table_type_id, :bottom_range_cents)
end
def update_rate(rate:)
diff --git a/app/views/components/_toolbar.html.erb b/app/views/components/_toolbar.html.erb
index c28240c..c0d842d 100644
--- a/app/views/components/_toolbar.html.erb
+++ b/app/views/components/_toolbar.html.erb
@@ -1,17 +1,19 @@
-
-
-
- <%= render partial: "components/toolbar" %>
-
-
-
@@ -43,7 +37,7 @@
<% FederalTaxTableType.all.each do |table| %>
- <%= form.radio_button :federal_tax_table_type_id, table.id, checked: table.id == @federal_tax_table_type_id, onchange: "this.form.requestSubmit()" %>
+ <%= form.radio_button :federal_tax_table_type_id, table.id, checked: table.id == @federal_tax_table_type_id, onchange: "this.form.requestSubmit()", class: "radio-button" %>
<%= form.label :federal_tax_table_type_id, table.filing_status.humanize.capitalize %>
<% end %>
@@ -95,5 +89,5 @@
<%= render partial: "shared/total_costs", locals: { total_cost: @total_cost } %>
-
-<% end %>
+ <% end %>
+
diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb
index 5ff9740..a2a1e0c 100644
--- a/app/views/dashboard/index.html.erb
+++ b/app/views/dashboard/index.html.erb
@@ -1 +1,2 @@
+<%= render partial: "components/toolbar", locals: { active_tab: :budget_calculator } %>
<%= render partial: "dashboard/index" %>
diff --git a/app/views/dashboard/index.turbo_stream.erb b/app/views/dashboard/index.turbo_stream.erb
new file mode 100644
index 0000000..5a27425
--- /dev/null
+++ b/app/views/dashboard/index.turbo_stream.erb
@@ -0,0 +1,2 @@
+<%= turbo_stream.replace "primary_frame", partial: "dashboard/index" %>
+<%= turbo_stream.replace "dashboard_toolbar", partial: "components/toolbar", locals: { active_tab: :budget_calculator } %>
\ No newline at end of file
diff --git a/app/views/federal_tax_brackets/_federal_tax_bracket.html.erb b/app/views/federal_tax_brackets/_federal_tax_bracket.html.erb
index 64728b6..6c00782 100644
--- a/app/views/federal_tax_brackets/_federal_tax_bracket.html.erb
+++ b/app/views/federal_tax_brackets/_federal_tax_bracket.html.erb
@@ -1,9 +1,9 @@
<%= turbo_frame_tag dom_id(federal_tax_bracket) do %>
-
- <% attributes = federal_tax_bracket.tier, humanized_money_with_symbol(federal_tax_bracket.bottom_range), humanized_money_with_symbol(federal_tax_bracket.top_range), number_to_percentage(federal_tax_bracket.rate * 100, precision: 1), humanized_money_with_symbol(federal_tax_bracket.cumulative) %>
+
+ <% attributes = federal_tax_bracket.federal_tax_table_type.filing_status.humanize.capitalize, federal_tax_bracket.tier, humanized_money_with_symbol(federal_tax_bracket.bottom_range), humanized_money_with_symbol(federal_tax_bracket.top_range), number_to_percentage(federal_tax_bracket.rate * 100, precision: 1), humanized_money_with_symbol(federal_tax_bracket.cumulative) %>
<% attributes.each do |attribute| %>
-
<%= attribute %>
+
<%= attribute %>
<% end %>
-
<%= link_to 'Edit', edit_federal_tax_bracket_path(federal_tax_bracket), class: "rounded-lg py-3 ml-2 px-5 bg-gray-100 inline-block font-medium" %>
+
<%= link_to 'Edit', edit_federal_tax_bracket_path(federal_tax_bracket), class: "btn btn-primary" %>
<% end %>
diff --git a/app/views/federal_tax_brackets/_index.html.erb b/app/views/federal_tax_brackets/_index.html.erb
index f8c8f13..b133a60 100644
--- a/app/views/federal_tax_brackets/_index.html.erb
+++ b/app/views/federal_tax_brackets/_index.html.erb
@@ -1,9 +1,30 @@
-
- <% tax_headings = %w[Tier From To Rate Cumulative] %>
- <% tax_headings.each do |tax_heading| %>
-
<%= tax_heading %>
+<%= turbo_frame_tag "primary_frame" do %>
+ <%= turbo_frame_tag :federal_tax_brackets do %>
+
+
+
+
+
Federal Tax Brackets
+ <%= link_to 'New federal tax bracket', new_federal_tax_bracket_path, class: "rounded-lg p-2 bg-primary-purple inline-block font-medium text-white" %>
+
+
+
+
+
+
+
+ <% tax_headings = ["Filing Status", "Tier", "From", "To", "Rate", "Cumulative"] %>
+ <% tax_headings.each do |tax_heading| %>
+
+ <%= tax_heading %>
+
+ <% end %>
+
+
+
+ <%= render @federal_tax_brackets %>
+
+
+
<% end %>
-
-<%= turbo_frame_tag :federal_tax_brackets do %>
- <%= render @federal_tax_brackets %>
<% end %>
diff --git a/app/views/federal_tax_brackets/index.html.erb b/app/views/federal_tax_brackets/index.html.erb
index e968b14..8c292dc 100644
--- a/app/views/federal_tax_brackets/index.html.erb
+++ b/app/views/federal_tax_brackets/index.html.erb
@@ -3,12 +3,5 @@
<%= notice %>
<% end %>
-
-
Federal Tax Brackets
- <%= link_to 'New federal tax bracket', new_federal_tax_bracket_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %>
-
-
-
- <%= render "federal_tax_brackets/index" %>
-
+ <%= render partial: "federal_tax_brackets/index" %>
diff --git a/app/views/federal_tax_brackets/index.turbo_stream.erb b/app/views/federal_tax_brackets/index.turbo_stream.erb
new file mode 100644
index 0000000..821b797
--- /dev/null
+++ b/app/views/federal_tax_brackets/index.turbo_stream.erb
@@ -0,0 +1,2 @@
+<%= turbo_stream.replace "primary_frame", partial: "federal_tax_brackets/index" %>
+<%= turbo_stream.replace "dashboard_toolbar", partial: "components/toolbar", locals: { active_tab: :federal_tax_brackets } %>
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 5823923..91033a0 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -9,6 +9,7 @@
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
+
diff --git a/config/importmap.rb b/config/importmap.rb
index 8dce42d..998d2fd 100644
--- a/config/importmap.rb
+++ b/config/importmap.rb
@@ -5,3 +5,4 @@
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
+pin "flowbite", to: "https://cdn.jsdelivr.net/npm/flowbite@2.5.2/dist/flowbite.turbo.min.js"
diff --git a/config/tailwind.config.js b/config/tailwind.config.js
index 39364de..c598649 100644
--- a/config/tailwind.config.js
+++ b/config/tailwind.config.js
@@ -12,6 +12,9 @@ module.exports = {
fontFamily: {
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
},
+ colors:{
+ 'primary-purple': '#5521B5',
+ }
},
},
plugins: [
@@ -19,5 +22,6 @@ module.exports = {
require('@tailwindcss/aspect-ratio'),
require('@tailwindcss/typography'),
require('@tailwindcss/container-queries'),
+ require('flowbite/plugin')
]
}
diff --git a/node_modules/.bin/mini-svg-data-uri b/node_modules/.bin/mini-svg-data-uri
new file mode 120000
index 0000000..20b061f
--- /dev/null
+++ b/node_modules/.bin/mini-svg-data-uri
@@ -0,0 +1 @@
+../mini-svg-data-uri/cli.js
\ No newline at end of file
diff --git a/node_modules/.bin/resolve b/node_modules/.bin/resolve
new file mode 120000
index 0000000..b6afda6
--- /dev/null
+++ b/node_modules/.bin/resolve
@@ -0,0 +1 @@
+../resolve/bin/resolve
\ No newline at end of file
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
new file mode 100644
index 0000000..02761ca
--- /dev/null
+++ b/node_modules/.package-lock.json
@@ -0,0 +1,191 @@
+{
+ "name": "finance",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
+ "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz",
+ "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+ },
+ "node_modules/flowbite": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/flowbite/-/flowbite-2.5.2.tgz",
+ "integrity": "sha512-kwFD3n8/YW4EG8GlY3Od9IoKND97kitO+/ejISHSqpn3vw2i5K/+ZI8Jm2V+KC4fGdnfi0XZ+TzYqQb4Q1LshA==",
+ "dependencies": {
+ "@popperjs/core": "^2.9.3",
+ "flowbite-datepicker": "^1.3.0",
+ "mini-svg-data-uri": "^1.4.3"
+ }
+ },
+ "node_modules/flowbite-datepicker": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flowbite-datepicker/-/flowbite-datepicker-1.3.0.tgz",
+ "integrity": "sha512-CLVqzuoE2vkUvWYK/lJ6GzT0be5dlTbH3uuhVwyB67+PjqJWABm2wv68xhBf5BqjpBxvTSQ3mrmLHpPJ2tvrSQ==",
+ "dependencies": {
+ "@rollup/plugin-node-resolve": "^15.2.3",
+ "flowbite": "^2.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
+ },
+ "node_modules/mini-svg-data-uri": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
+ "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+ "bin": {
+ "mini-svg-data-uri": "cli.js"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ }
+ }
+}
diff --git a/node_modules/@popperjs/core/LICENSE.md b/node_modules/@popperjs/core/LICENSE.md
new file mode 100644
index 0000000..0370c45
--- /dev/null
+++ b/node_modules/@popperjs/core/LICENSE.md
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2019 Federico Zivolo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/@popperjs/core/README.md b/node_modules/@popperjs/core/README.md
new file mode 100644
index 0000000..53be7b9
--- /dev/null
+++ b/node_modules/@popperjs/core/README.md
@@ -0,0 +1,376 @@
+
+
+
+
+
+
+
Tooltip & Popover Positioning Engine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+**Positioning tooltips and popovers is difficult. Popper is here to help!**
+
+Given an element, such as a button, and a tooltip element describing it, Popper
+will automatically put the tooltip in the right place near the button.
+
+It will position _any_ UI element that "pops out" from the flow of your document
+and floats near a target element. The most common example is a tooltip, but it
+also includes popovers, drop-downs, and more. All of these can be generically
+described as a "popper" element.
+
+## Demo
+
+[![Popper visualized](https://i.imgur.com/F7qWsmV.jpg)](https://popper.js.org)
+
+## Docs
+
+- [v2.x (latest)](https://popper.js.org/docs/v2/)
+- [v1.x](https://popper.js.org/docs/v1/)
+
+We've created a
+[Migration Guide](https://popper.js.org/docs/v2/migration-guide/) to help you
+migrate from Popper 1 to Popper 2.
+
+To contribute to the Popper website and documentation, please visit the
+[dedicated repository](https://github.com/popperjs/website).
+
+## Why not use pure CSS?
+
+- **Clipping and overflow issues**: Pure CSS poppers will not be prevented from
+ overflowing clipping boundaries, such as the viewport. It will get partially
+ cut off or overflows if it's near the edge since there is no dynamic
+ positioning logic. When using Popper, your popper will always be positioned in
+ the right place without needing manual adjustments.
+- **No flipping**: CSS poppers will not flip to a different placement to fit
+ better in view if necessary. While you can manually adjust for the main axis
+ overflow, this feature cannot be achieved via CSS alone. Popper automatically
+ flips the tooltip to make it fit in view as best as possible for the user.
+- **No virtual positioning**: CSS poppers cannot follow the mouse cursor or be
+ used as a context menu. Popper allows you to position your tooltip relative to
+ any coordinates you desire.
+- **Slower development cycle**: When pure CSS is used to position popper
+ elements, the lack of dynamic positioning means they must be carefully placed
+ to consider overflow on all screen sizes. In reusable component libraries,
+ this means a developer can't just add the component anywhere on the page,
+ because these issues need to be considered and adjusted for every time. With
+ Popper, you can place your elements anywhere and they will be positioned
+ correctly, without needing to consider different screen sizes, layouts, etc.
+ This massively speeds up development time because this work is automatically
+ offloaded to Popper.
+- **Lack of extensibility**: CSS poppers cannot be easily extended to fit any
+ arbitrary use case you may need to adjust for. Popper is built with
+ extensibility in mind.
+
+## Why Popper?
+
+With the CSS drawbacks out of the way, we now move on to Popper in the
+JavaScript space itself.
+
+Naive JavaScript tooltip implementations usually have the following problems:
+
+- **Scrolling containers**: They don't ensure the tooltip stays with the
+ reference element while scrolling when inside any number of scrolling
+ containers.
+- **DOM context**: They often require the tooltip move outside of its original
+ DOM context because they don't handle `offsetParent` contexts.
+- **Compatibility**: Popper handles an incredible number of edge cases regarding
+ different browsers and environments (mobile viewports, RTL, scrollbars enabled
+ or disabled, etc.). Popper is a popular and well-maintained library, so you
+ can be confident positioning will work for your users on any device.
+- **Configurability**: They often lack advanced configurability to suit any
+ possible use case.
+- **Size**: They are usually relatively large in size, or require an ancient
+ jQuery dependency.
+- **Performance**: They often have runtime performance issues and update the
+ tooltip position too slowly.
+
+**Popper solves all of these key problems in an elegant, performant manner.** It
+is a lightweight ~3 kB library that aims to provide a reliable and extensible
+positioning engine you can use to ensure all your popper elements are positioned
+in the right place.
+
+When you start writing your own popper implementation, you'll quickly run into
+all of the problems mentioned above. These widgets are incredibly common in our
+UIs; we've done the hard work figuring this out so you don't need to spend hours
+fixing and handling numerous edge cases that we already ran into while building
+the library!
+
+Popper is used in popular libraries like Bootstrap, Foundation, Material UI, and
+more. It's likely you've already used popper elements on the web positioned by
+Popper at some point in the past few years.
+
+Since we write UIs using powerful abstraction libraries such as React or Angular
+nowadays, you'll also be glad to know Popper can fully integrate with them and
+be a good citizen together with your other components. Check out `react-popper`
+for the official Popper wrapper for React.
+
+## Installation
+
+### 1. Package Manager
+
+```bash
+# With npm
+npm i @popperjs/core
+
+# With Yarn
+yarn add @popperjs/core
+```
+
+### 2. CDN
+
+```html
+
+
+
+
+
+```
+
+### 3. Direct Download?
+
+Managing dependencies by "directly downloading" them and placing them into your
+source code is not recommended for a variety of reasons, including missing out
+on feat/fix updates easily. Please use a versioning management system like a CDN
+or npm/Yarn.
+
+## Usage
+
+The most straightforward way to get started is to import Popper from the `unpkg`
+CDN, which includes all of its features. You can call the `Popper.createPopper`
+constructor to create new popper instances.
+
+Here is a complete example:
+
+```html
+
+
Popper example
+
+
+
+
I'm a button
+
I'm a tooltip
+
+
+
+```
+
+Visit the [tutorial](https://popper.js.org/docs/v2/tutorial/) for an example of
+how to build your own tooltip from scratch using Popper.
+
+### Module bundlers
+
+You can import the `createPopper` constructor from the fully-featured file:
+
+```js
+import { createPopper } from '@popperjs/core';
+
+const button = document.querySelector('#button');
+const tooltip = document.querySelector('#tooltip');
+
+// Pass the button, the tooltip, and some options, and Popper will do the
+// magic positioning for you:
+createPopper(button, tooltip, {
+ placement: 'right',
+});
+```
+
+All the modifiers listed in the docs menu will be enabled and "just work", so
+you don't need to think about setting Popper up. The size of Popper including
+all of its features is about 5 kB minzipped, but it may grow a bit in the
+future.
+
+#### Popper Lite (tree-shaking)
+
+If bundle size is important, you'll want to take advantage of tree-shaking. The
+library is built in a modular way to allow to import only the parts you really
+need.
+
+```js
+import { createPopperLite as createPopper } from '@popperjs/core';
+```
+
+The Lite version includes the most necessary modifiers that will compute the
+offsets of the popper, compute and add the positioning styles, and add event
+listeners. This is close in bundle size to pure CSS tooltip libraries, and
+behaves somewhat similarly.
+
+However, this does not include the features that makes Popper truly useful.
+
+The two most useful modifiers not included in Lite are `preventOverflow` and
+`flip`:
+
+```js
+import {
+ createPopperLite as createPopper,
+ preventOverflow,
+ flip,
+} from '@popperjs/core';
+
+const button = document.querySelector('#button');
+const tooltip = document.querySelector('#tooltip');
+
+createPopper(button, tooltip, {
+ modifiers: [preventOverflow, flip],
+});
+```
+
+As you make more poppers, you may be finding yourself needing other modifiers
+provided by the library.
+
+See [tree-shaking](https://popper.js.org/docs/v2/performance/#tree-shaking) for more
+information.
+
+## Distribution targets
+
+Popper is distributed in 3 different versions, in 3 different file formats.
+
+The 3 file formats are:
+
+- `esm` (works with `import` syntax — **recommended**)
+- `umd` (works with `
+
+
+
+