diff --git a/.env.example b/.env.example
index 2622021b..fd3e93c4 100644
--- a/.env.example
+++ b/.env.example
@@ -1,3 +1,12 @@
+# ================================ PLEASE READ ==========================================
+# This file outlines all the possible environment variables supported by the Maybe app.
+#
+# This includes several features that are for our "hosted" version of Maybe, which most
+# open-source contributors won't need.
+#
+# If you are developing locally, you should be referencing `.env.local.example` instead.
+# =======================================================================================
+
# Custom port config
# For users who have other applications listening at 3000, this allows them to set a value puma will listen to.
PORT=3000
diff --git a/.env.local.example b/.env.local.example
new file mode 100644
index 00000000..d393f623
--- /dev/null
+++ b/.env.local.example
@@ -0,0 +1,5 @@
+# To enable / disable self-hosting features.
+SELF_HOSTED=false
+
+# Enable Synth market data (careful, this will use your API credits)
+SYNTH_API_KEY=yourapikeyhere
diff --git a/.env.test b/.env.test
new file mode 100644
index 00000000..f47801f1
--- /dev/null
+++ b/.env.test
@@ -0,0 +1,8 @@
+SELF_HOSTED=false
+SYNTH_API_KEY=fookey
+
+# Set to true if you want SimpleCov reports generated
+COVERAGE=false
+
+# Set to true to run test suite serially
+DISABLE_PARALLELIZATION=false
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3e1cbccd..dc09d53e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,8 +10,8 @@
# Ignore all environment files (except templates).
/.env*
!/.env*.erb
-!.env.example
-!.env.test.example
+!.env.test
+!.env*.example
# Ignore all logfiles and tempfiles.
/log/*
diff --git a/README.md b/README.md
index d6dd1082..0372c4bd 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ After cloning the repo, the basic setup commands are:
```sh
cd maybe
-cp .env.example .env
+cp .env.local.example .env.local
bin/setup
bin/dev
diff --git a/app/assets/images/maybe-plus-background.png b/app/assets/images/maybe-plus-background.png
new file mode 100644
index 00000000..29d626d1
Binary files /dev/null and b/app/assets/images/maybe-plus-background.png differ
diff --git a/app/assets/images/maybe-plus-logo.png b/app/assets/images/maybe-plus-logo.png
new file mode 100644
index 00000000..3cede186
Binary files /dev/null and b/app/assets/images/maybe-plus-logo.png differ
diff --git a/app/assets/images/stripe-logo.svg b/app/assets/images/stripe-logo.svg
new file mode 100644
index 00000000..d95ded83
--- /dev/null
+++ b/app/assets/images/stripe-logo.svg
@@ -0,0 +1,6 @@
+
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 8fd5c552..e9788920 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,7 +2,22 @@ class ApplicationController < ActionController::Base
include Onboardable, Localize, AutoSync, Authentication, Invitable, SelfHostable, StoreLocation, Impersonatable
include Pagy::Backend
+ helper_method :require_upgrade?, :subscription_pending?
+
private
+ def require_upgrade?
+ return false if self_hosted?
+ return false unless Current.session
+ return false if Current.family.subscribed?
+ return false if subscription_pending? || request.path == settings_billing_path
+
+ true
+ end
+
+ def subscription_pending?
+ subscribed_at = Current.session.subscribed_at
+ subscribed_at.present? && subscribed_at <= Time.current && subscribed_at > 1.hour.ago
+ end
def with_sidebar
return "turbo_rails/frame" if turbo_frame_request?
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index 443770fe..ddc1ecaa 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -1,7 +1,7 @@
class CategoriesController < ApplicationController
layout :with_sidebar
- before_action :set_category, only: %i[edit update]
+ before_action :set_category, only: %i[edit update destroy]
before_action :set_transaction, only: :create
def index
@@ -13,12 +13,14 @@ class CategoriesController < ApplicationController
end
def create
- Category.transaction do
- category = Current.family.categories.create!(category_params)
- @transaction.update!(category_id: category.id) if @transaction
- end
+ @category = Current.family.categories.new(category_params)
- redirect_back_or_to transactions_path, notice: t(".success")
+ if @category.save
+ @transaction.update(category_id: @category.id) if @transaction
+ redirect_back_or_to transactions_path, notice: t(".success")
+ else
+ redirect_back_or_to transactions_path, alert: t(".failure", error: @category.errors.full_messages.to_sentence)
+ end
end
def edit
@@ -30,6 +32,12 @@ class CategoriesController < ApplicationController
redirect_back_or_to transactions_path, notice: t(".success")
end
+ def destroy
+ @category.destroy
+
+ redirect_back_or_to categories_path, notice: t(".success")
+ end
+
private
def set_category
@category = Current.family.categories.find(params[:id])
diff --git a/app/controllers/merchants_controller.rb b/app/controllers/merchants_controller.rb
index 33fe156c..252c5de6 100644
--- a/app/controllers/merchants_controller.rb
+++ b/app/controllers/merchants_controller.rb
@@ -12,8 +12,13 @@ class MerchantsController < ApplicationController
end
def create
- Current.family.merchants.create!(merchant_params)
- redirect_to merchants_path, notice: t(".success")
+ @merchant = Current.family.merchants.new(merchant_params)
+
+ if @merchant.save
+ redirect_to merchants_path, notice: t(".success")
+ else
+ redirect_to merchants_path, alert: t(".error", error: @merchant.errors.full_messages.to_sentence)
+ end
end
def edit
diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb
index ef634b83..e2c19535 100644
--- a/app/controllers/subscriptions_controller.rb
+++ b/app/controllers/subscriptions_controller.rb
@@ -1,16 +1,14 @@
class SubscriptionsController < ApplicationController
def new
- client = Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
-
if Current.family.stripe_customer_id.blank?
- customer = client.v1.customers.create(
+ customer = stripe_client.v1.customers.create(
email: Current.family.primary_user.email,
metadata: { family_id: Current.family.id }
)
Current.family.update(stripe_customer_id: customer.id)
end
- session = client.v1.checkout.sessions.create({
+ session = stripe_client.v1.checkout.sessions.create({
customer: Current.family.stripe_customer_id,
line_items: [ {
price: ENV["STRIPE_PLAN_ID"],
@@ -18,7 +16,7 @@ class SubscriptionsController < ApplicationController
} ],
mode: "subscription",
allow_promotion_codes: true,
- success_url: settings_billing_url,
+ success_url: success_subscription_url + "?session_id={CHECKOUT_SESSION_ID}",
cancel_url: settings_billing_url
})
@@ -26,12 +24,24 @@ class SubscriptionsController < ApplicationController
end
def show
- client = Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
-
- portal_session = client.v1.billing_portal.sessions.create(
+ portal_session = stripe_client.v1.billing_portal.sessions.create(
customer: Current.family.stripe_customer_id,
return_url: settings_billing_url
)
+
redirect_to portal_session.url, allow_other_host: true, status: :see_other
end
+
+ def success
+ checkout_session = stripe_client.v1.checkout.sessions.retrieve(params[:session_id])
+ Current.session.update(subscribed_at: Time.at(checkout_session.created))
+ redirect_to root_path, notice: "You have successfully subscribed to Maybe+."
+ rescue Stripe::InvalidRequestError
+ redirect_to settings_billing_path, alert: "Something went wrong processing your subscription. Please contact us to get this fixed."
+ end
+
+ private
+ def stripe_client
+ @stripe_client ||= Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
+ end
end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index c2feb537..2b81e7cd 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -1,7 +1,7 @@
class TagsController < ApplicationController
layout :with_sidebar
- before_action :set_tag, only: %i[edit update]
+ before_action :set_tag, only: %i[edit update destroy]
def index
@tags = Current.family.tags.alphabetically
@@ -12,8 +12,13 @@ class TagsController < ApplicationController
end
def create
- Current.family.tags.create!(tag_params)
- redirect_to tags_path, notice: t(".created")
+ @tag = Current.family.tags.new(tag_params)
+
+ if @tag.save
+ redirect_to tags_path, notice: t(".created")
+ else
+ redirect_to tags_path, alert: t(".error", error: @tag.errors.full_messages.to_sentence)
+ end
end
def edit
@@ -24,6 +29,11 @@ class TagsController < ApplicationController
redirect_to tags_path, notice: t(".updated")
end
+ def destroy
+ @tag.destroy!
+ redirect_to tags_path, notice: t(".deleted")
+ end
+
private
def set_tag
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
index f127905d..4f4e0272 100644
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -5,10 +5,10 @@ module SettingsHelper
{ name: I18n.t("settings.nav.self_hosting_label"), path: :settings_hosting_path, condition: :self_hosted? },
{ name: I18n.t("settings.nav.billing_label"), path: :settings_billing_path },
{ name: I18n.t("settings.nav.accounts_label"), path: :accounts_path },
+ { name: I18n.t("settings.nav.imports_label"), path: :imports_path },
{ name: I18n.t("settings.nav.tags_label"), path: :tags_path },
{ name: I18n.t("settings.nav.categories_label"), path: :categories_path },
{ name: I18n.t("settings.nav.merchants_label"), path: :merchants_path },
- { name: I18n.t("settings.nav.imports_label"), path: :imports_path },
{ name: I18n.t("settings.nav.whats_new_label"), path: :changelog_path },
{ name: I18n.t("settings.nav.feedback_label"), path: :feedback_path }
]
diff --git a/app/helpers/styled_form_builder.rb b/app/helpers/styled_form_builder.rb
index f9e060af..c7e27b0a 100644
--- a/app/helpers/styled_form_builder.rb
+++ b/app/helpers/styled_form_builder.rb
@@ -49,7 +49,12 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
end
def submit(value = nil, options = {})
- merged_options = { class: "btn btn--primary w-full" }.merge(options)
+ default_options = {
+ data: { turbo_submits_with: "Submitting..." },
+ class: "btn btn--primary w-full"
+ }
+
+ merged_options = default_options.merge(options)
value, options = nil, value if value.is_a?(Hash)
super(value, merged_options)
end
diff --git a/app/models/account_import.rb b/app/models/account_import.rb
index 3987a1ff..98e7e0d0 100644
--- a/app/models/account_import.rb
+++ b/app/models/account_import.rb
@@ -14,6 +14,14 @@ class AccountImport < Import
)
account.save!
+
+ account.entries.create!(
+ amount: row.amount,
+ currency: row.currency,
+ date: Date.current,
+ name: "Imported account value",
+ entryable: Account::Valuation.new
+ )
end
end
end
diff --git a/app/models/category.rb b/app/models/category.rb
index 3744295a..4a2d6361 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -4,6 +4,7 @@ class Category < ApplicationRecord
belongs_to :family
validates :name, :color, :family, presence: true
+ validates :name, uniqueness: { scope: :family_id }
before_update :clear_internal_category, if: :name_changed?
diff --git a/app/models/demo/generator.rb b/app/models/demo/generator.rb
index 20e5c01c..ba210b2b 100644
--- a/app/models/demo/generator.rb
+++ b/app/models/demo/generator.rb
@@ -71,7 +71,8 @@ class Demo::Generator
first_name: "Demo",
last_name: "User",
role: "admin",
- password: "password"
+ password: "password",
+ onboarded_at: Time.current
end
def create_tags!
diff --git a/app/models/family.rb b/app/models/family.rb
index c4949a4d..ddfdab3e 100644
--- a/app/models/family.rb
+++ b/app/models/family.rb
@@ -132,7 +132,7 @@ class Family < ApplicationRecord
end
def subscribed?
- stripe_subscription_status.present? && stripe_subscription_status == "active"
+ stripe_subscription_status == "active"
end
def primary_user
diff --git a/app/models/merchant.rb b/app/models/merchant.rb
index 3d1448e2..e363f6aa 100644
--- a/app/models/merchant.rb
+++ b/app/models/merchant.rb
@@ -3,6 +3,7 @@ class Merchant < ApplicationRecord
belongs_to :family
validates :name, :color, :family, presence: true
+ validates :name, uniqueness: { scope: :family }
scope :alphabetically, -> { order(:name) }
diff --git a/app/views/categories/_category.html.erb b/app/views/categories/_category.html.erb
index f25e5c25..97f19775 100644
--- a/app/views/categories/_category.html.erb
+++ b/app/views/categories/_category.html.erb
@@ -9,11 +9,15 @@
<%= contextual_menu_modal_action_item t(".edit"), edit_category_path(category) %>
- <%= link_to new_category_deletion_path(category),
+ <% if category.transactions.any? %>
+ <%= link_to new_category_deletion_path(category),
class: "flex items-center w-full rounded-lg text-red-600 hover:bg-red-50 py-2 px-3 gap-2",
data: { turbo_frame: :modal } do %>
- <%= lucide_icon "trash-2", class: "shrink-0 w-5 h-5" %>
- <%= t(".delete") %>
+ <%= lucide_icon "trash-2", class: "shrink-0 w-5 h-5" %>
+ <%= t(".delete") %>
+ <% end %>
+ <% else %>
+ <%= contextual_menu_destructive_item t(".delete"), category_path(category), turbo_confirm: nil %>
<% end %>
<% end %>
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb
index 5f36f8d9..313e48ba 100644
--- a/app/views/categories/_form.html.erb
+++ b/app/views/categories/_form.html.erb
@@ -1,5 +1,5 @@
- <%= styled_form_with model: category, class: "space-y-4", data: { turbo: false } do |f| %>
+ <%= styled_form_with model: category, class: "space-y-4", data: { turbo_frame: :_top } do |f| %>
<%= render partial: "shared/color_avatar", locals: { name: category.name, color: category.color } %>
@@ -13,7 +13,7 @@
<% end %>
- <%= f.text_field :name, placeholder: t(".placeholder"), class: "text-sm font-normal placeholder:text-gray-500 h-10 relative pl-3 w-full border-none rounded-lg", required: true, data: { color_avatar_target: "name" } %>
+ <%= f.text_field :name, placeholder: t(".placeholder"), required: true, autofocus: true, data: { color_avatar_target: "name" } %>
diff --git a/app/views/layouts/with_sidebar.html.erb b/app/views/layouts/with_sidebar.html.erb
index ca824d45..6551526b 100644
--- a/app/views/layouts/with_sidebar.html.erb
+++ b/app/views/layouts/with_sidebar.html.erb
@@ -7,7 +7,12 @@
<%= render "layouts/sidebar" %>
<% end %>
-
+
+ ">
+ <% if require_upgrade? %>
+ <%= render "shared/subscribe_modal" %>
+ <% end %>
+
<%= yield %>
diff --git a/app/views/merchants/_form.html.erb b/app/views/merchants/_form.html.erb
index 4b748f67..93efecb9 100644
--- a/app/views/merchants/_form.html.erb
+++ b/app/views/merchants/_form.html.erb
@@ -1,5 +1,5 @@
- <%= styled_form_with model: @merchant, class: "space-y-4", data: { turbo: false } do |f| %>
+ <%= styled_form_with model: @merchant, class: "space-y-4", data: { turbo_frame: :_top } do |f| %>
<%= render partial: "shared/color_avatar", locals: { name: @merchant.name, color: @merchant.color } %>
@@ -13,7 +13,7 @@
<% end %>
- <%= f.text_field :name, placeholder: t(".name_placeholder"), class: "text-sm font-normal placeholder:text-gray-500 h-10 relative pl-3 w-full border-none rounded-lg", required: true, data: { color_avatar_target: "name" } %>
+ <%= f.text_field :name, placeholder: t(".name_placeholder"), autofocus: true, required: true, data: { color_avatar_target: "name" } %>
diff --git a/app/views/merchants/_merchant.html.erb b/app/views/merchants/_merchant.html.erb
index 33fba7ee..2b964140 100644
--- a/app/views/merchants/_merchant.html.erb
+++ b/app/views/merchants/_merchant.html.erb
@@ -15,11 +15,11 @@
<%= contextual_menu_destructive_item t(".delete"),
merchant_path(merchant),
turbo_frame: "_top",
- turbo_confirm: {
+ turbo_confirm: merchant.transactions.any? ? {
title: t(".confirm_title"),
body: t(".confirm_body"),
accept: t(".confirm_accept")
- } %>
+ } : nil %>
<% end %>
diff --git a/app/views/onboardings/preferences.html.erb b/app/views/onboardings/preferences.html.erb
index 84712a3e..26b0ac1f 100644
--- a/app/views/onboardings/preferences.html.erb
+++ b/app/views/onboardings/preferences.html.erb
@@ -8,8 +8,8 @@
<%= t(".subtitle") %>
-
-
+
+
<%= tag.p t(".example"), class: "text-gray-500 text-sm" %>
<%= tag.p "$2,323.25", class: "text-gray-900 font-medium text-2xl" %>
diff --git a/app/views/pages/dashboard.html.erb b/app/views/pages/dashboard.html.erb
index b25e8497..f3846a4a 100644
--- a/app/views/pages/dashboard.html.erb
+++ b/app/views/pages/dashboard.html.erb
@@ -24,9 +24,7 @@
- <% if !Current.family.subscribed? && !self_hosted? %>
- <%= render "shared/subscribe_prompt" %>
- <% elsif @accounts.empty? %>
+ <% if @accounts.empty? %>
<%= render "shared/no_account_empty_state" %>
<% else %>
diff --git a/app/views/settings/billings/show.html.erb b/app/views/settings/billings/show.html.erb
index c3ed66bc..45b9c702 100644
--- a/app/views/settings/billings/show.html.erb
+++ b/app/views/settings/billings/show.html.erb
@@ -5,11 +5,42 @@
<%= t(".page_title") %>
<%= settings_section title: t(".subscription_title"), subtitle: t(".subscription_subtitle") do %>
- <% if @user.family.stripe_plan_id.blank? %>
- <%= link_to t(".subscribe_button"), new_subscription_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2", data: { turbo: false } %>
- <% else %>
- <%= link_to t(".manage_subscription_button"), subscription_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2", data: { turbo: false } %>
- <% end %>
+
+
+
+
+ <%= lucide_icon "gem", class: "w-5 h-5 text-gray-500" %>
+
+
+
+ <% if @user.family.subscribed? || subscription_pending? %>
+
You are currently subscribed to Maybe+
+
Manage your billing settings here.
+ <% else %>
+
You are currently not subscribed
+
Once you subscribe to Maybe+, you’ll see your billing settings here.
+ <% end %>
+
+
+
+ <% if @user.family.subscribed? || subscription_pending? %>
+ <%= link_to subscription_path, class: "btn btn--secondary flex items-center gap-1" do %>
+
Manage
+ <%= lucide_icon "external-link", class: "w-5 h-5 shrink-0 text-gray-500" %>
+ <% end %>
+ <% else %>
+ <%= link_to new_subscription_path, class: "btn btn--secondary flex items-center gap-1" do %>
+
Subscribe
+ <%= lucide_icon "external-link", class: "w-5 h-5 shrink-0 text-gray-500" %>
+ <% end %>
+ <% end %>
+
+
+
+ <%= image_tag "stripe-logo.svg", class: "w-5 h-5 shrink-0" %>
+
Managed via Stripe
+
+
<% end %>
<%= settings_nav_footer %>
diff --git a/app/views/shared/_subscribe_modal.html.erb b/app/views/shared/_subscribe_modal.html.erb
new file mode 100644
index 00000000..463c195a
--- /dev/null
+++ b/app/views/shared/_subscribe_modal.html.erb
@@ -0,0 +1,25 @@
+
+
+
+
'); background-size: cover; background-position: center;">
+
+
+
+ <%= image_tag "maybe-plus-logo.png", class: "w-16" %>
+
+
+
Join Maybe+
+
+
+
Nobody likes paywalls, but we need feedback from users willing to pay for Maybe.
+
+
To continue using the app, please subscribe. In this early beta testing phase, we require that you upgrade within 1 hour to claim your spot.
+
+
+ <%= link_to "Upgrade to Maybe+", new_subscription_path, class: "btn btn--primary text-center w-full block" %>
+
+
+
+
+
+
diff --git a/app/views/shared/_subscribe_prompt.html.erb b/app/views/shared/_subscribe_prompt.html.erb
deleted file mode 100644
index 35315af4..00000000
--- a/app/views/shared/_subscribe_prompt.html.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- <%= lucide_icon "circle-fading-arrow-up", class: "w-8 h-8 text-green-500" %>
-
-
-
<%= t(".title") %>
-
<%= t(".subtitle") %>
-
<%= t(".guarantee") %>
-
-
- <%= link_to new_subscription_path, class: "btn btn--primary flex items-center gap-1" do %>
- <%= lucide_icon("credit-card", class: "w-5 h-5") %>
-
<%= t(".subscribe") %>
- <% end %>
-
-
diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb
index 99b1c706..395a1f03 100644
--- a/app/views/tags/_form.html.erb
+++ b/app/views/tags/_form.html.erb
@@ -1,5 +1,5 @@
- <%= styled_form_with model: tag, class: "space-y-4", data: { turbo: false } do |f| %>
+ <%= styled_form_with model: tag, class: "space-y-4", data: { turbo_frame: :_top } do |f| %>
<%= render partial: "shared/color_avatar", locals: { name: tag.name, color: tag.color } %>
@@ -13,7 +13,7 @@
<% end %>
- <%= f.text_field :name, placeholder: t(".placeholder"), class: "text-sm font-normal placeholder:text-gray-500 h-10 relative pl-3 w-full border-none rounded-lg", required: true, data: { color_avatar_target: "name" } %>
+ <%= f.text_field :name, placeholder: t(".placeholder"), autofocus: true, required: true, data: { color_avatar_target: "name" } %>
diff --git a/app/views/tags/_tag.html.erb b/app/views/tags/_tag.html.erb
index 5a65a341..ed325d74 100644
--- a/app/views/tags/_tag.html.erb
+++ b/app/views/tags/_tag.html.erb
@@ -12,11 +12,15 @@
<%= contextual_menu_modal_action_item t(".edit"), edit_tag_path(tag) %>
- <%= link_to new_tag_deletion_path(tag),
+ <% if tag.transactions.any? %>
+ <%= link_to new_tag_deletion_path(tag),
class: "block w-full py-2 px-3 space-x-2 text-red-600 hover:bg-red-50 flex items-center rounded-lg",
data: { turbo_frame: :modal } do %>
- <%= lucide_icon "trash-2", class: "w-5 h-5" %>
- <%= t(".delete") %>
+ <%= lucide_icon "trash-2", class: "w-5 h-5" %>
+ <%= t(".delete") %>
+ <% end %>
+ <% else %>
+ <%= contextual_menu_destructive_item t(".delete"), tag_path(tag), turbo_confirm: nil %>
<% end %>
<% end %>
diff --git a/config/locales/views/categories/en.yml b/config/locales/views/categories/en.yml
index 5ef738c0..6dd57a4c 100644
--- a/config/locales/views/categories/en.yml
+++ b/config/locales/views/categories/en.yml
@@ -5,7 +5,10 @@ en:
delete: Delete category
edit: Edit category
create:
+ failure: 'Failed to create category: %{error}'
success: New transaction category created successfully
+ destroy:
+ success: Category deleted successfully
edit:
edit: Edit category
form:
diff --git a/config/locales/views/merchants/en.yml b/config/locales/views/merchants/en.yml
index b95aa729..3f31dd59 100644
--- a/config/locales/views/merchants/en.yml
+++ b/config/locales/views/merchants/en.yml
@@ -2,6 +2,7 @@
en:
merchants:
create:
+ error: 'Error creating merchant: %{error}'
success: New merchant created successfully
destroy:
success: Merchant deleted successfully
diff --git a/config/locales/views/settings/en.yml b/config/locales/views/settings/en.yml
index 205be0f8..0e2fe635 100644
--- a/config/locales/views/settings/en.yml
+++ b/config/locales/views/settings/en.yml
@@ -3,9 +3,7 @@ en:
settings:
billings:
show:
- manage_subscription_button: Manage subscription
page_title: Billing
- subscribe_button: Subscribe
subscription_subtitle: Manage your subscription and billing details
subscription_title: Manage subscription
nav:
diff --git a/config/locales/views/shared/en.yml b/config/locales/views/shared/en.yml
index 89ad83bc..80f4fc3d 100644
--- a/config/locales/views/shared/en.yml
+++ b/config/locales/views/shared/en.yml
@@ -13,12 +13,6 @@ en:
no_account_subtitle: Since no accounts have been added, there's no data to display.
Add your first accounts to start viewing dashboard data.
no_account_title: No accounts yet
- subscribe_prompt:
- guarantee: We're reasonable people here. If you're not happy or something doesn't
- work, we'll gladly refund you.
- subscribe: Upgrade your account
- subtitle: To continue using Maybe, please subscribe!
- title: Upgrade
upgrade_notification:
app_upgraded: The app has been upgraded to %{version}.
dismiss: Dismiss
diff --git a/config/locales/views/tags/en.yml b/config/locales/views/tags/en.yml
index 4a78e350..a1f2ba32 100644
--- a/config/locales/views/tags/en.yml
+++ b/config/locales/views/tags/en.yml
@@ -3,6 +3,9 @@ en:
tags:
create:
created: Tag created
+ error: 'Error creating tag: %{error}'
+ destroy:
+ deleted: Tag deleted
edit:
edit: Edit tag
form:
diff --git a/config/routes.rb b/config/routes.rb
index 94fcd02c..2d6fe452 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -26,9 +26,11 @@ Rails.application.routes.draw do
resource :billing, only: :show
end
- resource :subscription, only: %i[new show]
+ resource :subscription, only: %i[new show] do
+ get :success, on: :collection
+ end
- resources :tags, except: %i[show destroy] do
+ resources :tags, except: :show do
resources :deletions, only: %i[new create], module: :tag
end
diff --git a/db/migrate/20241024142537_add_subscription_timestamp_to_session.rb b/db/migrate/20241024142537_add_subscription_timestamp_to_session.rb
new file mode 100644
index 00000000..0f9677a2
--- /dev/null
+++ b/db/migrate/20241024142537_add_subscription_timestamp_to_session.rb
@@ -0,0 +1,5 @@
+class AddSubscriptionTimestampToSession < ActiveRecord::Migration[7.2]
+ def change
+ add_column :sessions, :subscribed_at, :datetime
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d9fb2e48..7fe73452 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.2].define(version: 2024_10_22_221544) do
+ActiveRecord::Schema[7.2].define(version: 2024_10_24_142537) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -496,6 +496,7 @@ ActiveRecord::Schema[7.2].define(version: 2024_10_22_221544) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.uuid "active_impersonator_session_id"
+ t.datetime "subscribed_at"
t.index ["active_impersonator_session_id"], name: "index_sessions_on_active_impersonator_session_id"
t.index ["user_id"], name: "index_sessions_on_user_id"
end
diff --git a/test/fixtures/families.yml b/test/fixtures/families.yml
index c1b0831a..57697046 100644
--- a/test/fixtures/families.yml
+++ b/test/fixtures/families.yml
@@ -1,6 +1,8 @@
empty:
name: Family
+ stripe_subscription_status: active
dylan_family:
name: The Dylan Family
+ stripe_subscription_status: active
diff --git a/test/fixtures/files/imports/accounts.csv b/test/fixtures/files/imports/accounts.csv
index fb3974f8..a24b1f81 100644
--- a/test/fixtures/files/imports/accounts.csv
+++ b/test/fixtures/files/imports/accounts.csv
@@ -1,5 +1,5 @@
type,name,amount,currency
Checking,Main Checking Account,5000.00,USD
Savings,Emergency Fund,10000.00,USD
-Credit Card,Rewards Credit Card,-1500.00,USD
+Credit Card,Rewards Credit Card,1500.00,USD
Investment,Retirement Portfolio,75000.00,USD
diff --git a/test/test_helper.rb b/test/test_helper.rb
index b3bacfa8..6b386535 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -7,8 +7,6 @@ end
require_relative "../config/environment"
-ENV["SELF_HOSTED"] = "false"
-ENV["UPGRADES_ENABLED"] = "false"
ENV["RAILS_ENV"] ||= "test"
# Fixes Segfaults on M1 Macs when running tests in parallel (temporary workaround)