1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-18 20:59:39 +02:00
Maybe/app/models/trend.rb
Zach Gollwitzer d75be2282b
New Design System + Codebase Refresh (#1823)
Since the very first 0.1.0-alpha.1 release, we've been moving quickly to add new features to the Maybe app. In doing so, some parts of the codebase have become outdated, unnecessary, or overly-complex as a natural result of this feature prioritization.

Now that "core" Maybe is complete, we're moving into a second phase of development where we'll be working hard to improve the accuracy of existing features and build additional features on top of "core". This PR is a quick overhaul of the existing codebase aimed to:

- Establish the brand new and simplified dashboard view (pictured above)
- Establish and move towards the conventions introduced in Cursor rules and project design overview #1788
- Consolidate layouts and improve the performance of layout queries
- Organize the core models of the Maybe domain (i.e. Account::Entry, Account::Transaction, etc.) and break out specific traits of each model into dedicated concerns for better readability
- Remove stale / dead code from codebase
- Remove overly complex code paths in favor of simpler ones
2025-02-21 11:57:59 -05:00

94 lines
1.6 KiB
Ruby

class Trend
include ActiveModel::Validations
DIRECTIONS = %w[up down].freeze
attr_reader :current, :previous, :favorable_direction
validates :current, presence: true
def initialize(current:, previous:, favorable_direction: nil)
@current = current
@previous = previous || 0
@favorable_direction = (favorable_direction.presence_in(DIRECTIONS) || "up").inquiry
validate!
end
def direction
if current == previous
"flat"
elsif current > previous
"up"
else
"down"
end.inquiry
end
def color
case direction
when "up"
favorable_direction.down? ? red_hex : green_hex
when "down"
favorable_direction.down? ? green_hex : red_hex
else
gray_hex
end
end
def icon
if direction.flat?
"minus"
elsif direction.up?
"arrow-up"
else
"arrow-down"
end
end
def value
current - previous
end
def percent
return 0.0 if previous.zero? && current.zero?
return Float::INFINITY if previous.zero?
change = (current - previous).to_f
(change / previous.to_f * 100).round(1)
end
def percent_formatted
if percent.finite?
"#{percent.round(1)}%"
else
percent > 0 ? "+∞" : "-∞"
end
end
def as_json
{
value: value,
percent: percent,
percent_formatted: percent_formatted,
current: current,
previous: previous,
color: color,
icon: icon
}
end
private
def red_hex
"var(--color-destructive)"
end
def green_hex
"var(--color-success)"
end
def gray_hex
"var(--color-gray)"
end
end