chore: init commit
in worker.../repo/GITFOLDER.zip is the .git folder.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
<%= form_with(
|
||||
model: order,
|
||||
class: "w-full max-w-md mx-auto",
|
||||
data: {
|
||||
controller: "order-form",
|
||||
order_form_current_price_value: order.stock.current_price,
|
||||
turbo_frame: "_top"
|
||||
}
|
||||
) do |form| %>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<% if order.errors.any? %>
|
||||
<div class="mb-6 p-4 bg-[var(--sitf-status-destructive)]/10 border border-[var(--sitf-status-destructive)]/20 rounded-lg">
|
||||
<h4 class="text-[var(--sitf-status-destructive)] font-medium mb-2">
|
||||
Please fix the following errors:
|
||||
</h4>
|
||||
<ul class="text-[var(--sitf-status-destructive)] text-sm space-y-1">
|
||||
<% order.errors.each do |error| %>
|
||||
<li>• <%= error.full_message %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="text-center mb-6">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-1">
|
||||
<%= order.action&.titlecase %> <%= order.stock.ticker %>
|
||||
</h2>
|
||||
<p class="text-gray-600">
|
||||
<%= number_to_currency(order.stock.current_price) %> per share
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Account Info -->
|
||||
<div class="grid grid-cols-2 gap-4 mb-6">
|
||||
<div class="bg-[var(--sitf-secondary-chart2)]/10 border border-[var(--sitf-secondary-chart2)]/20 p-4 rounded-lg text-center">
|
||||
<p class="text-sm text-[var(--sitf-secondary-chart2)] font-medium mb-1">
|
||||
Available Cash
|
||||
</p>
|
||||
<p class="font-semibold text-[var(--sitf-foreground)]">
|
||||
<%= number_to_currency(current_user&.portfolio&.cash_balance) %>
|
||||
</p>
|
||||
</div>
|
||||
<div class="bg-[var(--sitf-ring)]/10 border border-[var(--sitf-ring)]/20 p-4 rounded-lg text-center">
|
||||
<p class="text-sm text-[#8b5cf6] font-medium mb-1">
|
||||
Shares Owned
|
||||
</p>
|
||||
<p class="font-semibold text-[var(--sitf-foreground)]" data-testid="shares-owned-value">
|
||||
<%= shares_owned %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shares Input -->
|
||||
<div class="mb-6">
|
||||
<%= form.label :shares,
|
||||
"Number of shares",
|
||||
class: "block text-sm font-medium text-[var(--sitf-foreground)] mb-2" %>
|
||||
<%= form.number_field :shares,
|
||||
min: 1,
|
||||
step: 1,
|
||||
required: true,
|
||||
placeholder: "Enter quantity",
|
||||
class: "w-full px-4 py-3 text-lg border-2 border-[var(--sitf-muted)] rounded-lg focus:ring-2 focus:ring-[var(--sitf-ring)] focus:border-[var(--sitf-ring)] outline-none",
|
||||
data: {
|
||||
order_form_target: "shares",
|
||||
action: "input->order-form#calculateTotal"
|
||||
} %>
|
||||
</div>
|
||||
|
||||
<!-- Order Total -->
|
||||
<div class="mb-6 p-4 bg-[var(--sitf-ring)]/10 border border-[var(--sitf-ring)]/20 rounded-lg">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<span class="text-[var(--sitf-foreground)] font-medium">
|
||||
Total <%= order.action == 'buy' ? 'Cost' : 'Proceeds' %>:
|
||||
</span>
|
||||
<span class="text-xl font-bold text-[var(--sitf-foreground)]"
|
||||
data-order-form-target="totalCost">
|
||||
$0.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Daily Transaction Fee Notice -->
|
||||
<div class="pt-2 border-t border-[var(--sitf-muted)]/20">
|
||||
<p class="text-xs text-[var(--sitf-muted-foreground)] flex items-center">
|
||||
<svg class="w-4 h-4 mr-2 text-[var(--sitf-secondary-chart2)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
Trading fee: $1 per day
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hidden Fields -->
|
||||
<%= form.hidden_field :action, value: order.action %>
|
||||
<%= form.hidden_field :stock_id, value: order.stock.id %>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="flex gap-3">
|
||||
<button type="button"
|
||||
class="flex-1 px-4 py-3 border border-[var(--sitf-8)]/50 text-[var(--sitf-input)] font-medium rounded-lg hover:bg-[var(--sitf-8)]/10 transition-colors cursor-pointer"
|
||||
data-action="click->modal#close">
|
||||
Cancel
|
||||
</button>
|
||||
<%= form.submit "#{order.action == 'buy' ? 'Buy' : 'Sell'} Shares",
|
||||
class: "flex-1 px-4 py-3 #{order.action == 'buy' ? 'bg-[var(--sitf-secondary-chart2)] hover:bg-[var(--sitf-secondary-chart2)]/90' : 'bg-[var(--sitf-accent2-chart5)] hover:bg-[var(--sitf-accent2-chart5)]/90'} text-[var(--sitf-primary-secondary-foreground-card)] font-medium rounded-lg transition-colors shadow-sm cursor-pointer" %>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
@@ -0,0 +1,40 @@
|
||||
<div id="<%= dom_id order %>" class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500 font-medium">Stock</p>
|
||||
<p class="text-lg font-semibold"><%= order.stock.company_name %></p>
|
||||
<p class="text-sm text-gray-400"><%= order.stock.ticker %></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-sm text-gray-500 font-medium">Shares</p>
|
||||
<p class="text-lg font-semibold"><%= order.shares %></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-sm text-gray-500 font-medium">Status</p>
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
||||
<%= case order.status
|
||||
when 'pending'
|
||||
'bg-yellow-100 text-yellow-800'
|
||||
when 'completed'
|
||||
'bg-green-100 text-green-800'
|
||||
when 'canceled'
|
||||
'bg-red-100 text-red-800'
|
||||
else
|
||||
'bg-gray-100 text-gray-800'
|
||||
end %>">
|
||||
<%= order.status.capitalize %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-sm text-gray-500 font-medium">Total Cost</p>
|
||||
<p class="text-lg font-semibold">
|
||||
<% if order.stock.price_cents && order.shares %>
|
||||
<%= number_to_currency(order.purchase_cost / 100.0) %>
|
||||
<% else %>
|
||||
<span class="text-gray-400">Price unavailable</span>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! order, :id, :student_id, :stock_id, :shares, :status, :created_at, :updated_at
|
||||
json.url order_url(order, format: :json)
|
||||
@@ -0,0 +1,3 @@
|
||||
<turbo-frame id="modal_frame">
|
||||
<%= render "form", order: @order, transaction_type: @order.existing_transaction_type, shares_owned: @shares_owned %>
|
||||
</turbo-frame>
|
||||
@@ -0,0 +1,145 @@
|
||||
<div class="flex flex-col h-full w-full">
|
||||
<% if notice.present? %>
|
||||
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice">
|
||||
<%= notice %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<header class="flex items-center justify-between px-6 py-4 border-b">
|
||||
<h1 class="text-2xl font-bold py-2">Transactions</h1>
|
||||
</header>
|
||||
|
||||
<main class="flex-1 p-6">
|
||||
<%= render "shared/table_container" do %>
|
||||
<thead>
|
||||
<tr class="table-header-row min-w-full">
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:created_at, "Date") %>
|
||||
</th>
|
||||
<% if current_user&.teacher_or_admin? %>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:username, "Username") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:classroom, "Class") %>
|
||||
</th>
|
||||
<% end %>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:stock, "Stock") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:price_per_share, "Price per share") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:shares, "Shares") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
<%= sort_link(:status, "Status") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-left">
|
||||
Type
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-right">
|
||||
<%= sort_link(:total_cost, "Total Cost") %>
|
||||
</th>
|
||||
<th class="table-header-cell table-header-cell-right" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if @orders.any? %>
|
||||
<% @orders.each do |order| %>
|
||||
<tr id="<%= dom_id(order) %>" class="table-body-row">
|
||||
<td class="table-body-cell">
|
||||
<span class="table-cell-content">
|
||||
<%= order.created_at.to_date %>
|
||||
</span>
|
||||
</td>
|
||||
<% if current_user&.teacher_or_admin? %>
|
||||
<td class="table-body-cell">
|
||||
<span class="table-cell-content">
|
||||
<%= order.user.username %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="table-body-cell">
|
||||
<span class="table-cell-content">
|
||||
<%= order.user.classroom&.name || "-" %>
|
||||
</span>
|
||||
</td>
|
||||
<% end %>
|
||||
<td class="table-body-cell">
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="font-medium text-base text-black leading-tight">
|
||||
<%= order.stock.company_name %>
|
||||
</span>
|
||||
<span class="text-sm text-gray-600 leading-tight">
|
||||
<%= order.stock.ticker %>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="table-body-cell">
|
||||
<span class="table-cell-content">
|
||||
$<%= order.stock.current_price %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="table-body-cell">
|
||||
<span class="table-cell-content">
|
||||
<%= order.shares %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="table-body-cell">
|
||||
<div class="box-border content-stretch flex gap-2 h-9 items-center justify-center px-4 py-2 relative rounded-[16px] shrink-0 inline-flex
|
||||
<%= case order.status
|
||||
when 'pending'
|
||||
'bg-yellow-100 text-yellow-800'
|
||||
when 'completed'
|
||||
'bg-green-100 text-green-800'
|
||||
when 'canceled'
|
||||
'bg-red-100 text-red-800'
|
||||
else
|
||||
'bg-gray-100 text-gray-800'
|
||||
end %>">
|
||||
<div class="font-medium leading-[0] relative shrink-0 text-[14px] text-nowrap">
|
||||
<p class="leading-[20px] whitespace-pre"><%= order.status.capitalize %></p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="table-body-cell">
|
||||
<%= order.action.capitalize %>
|
||||
</td>
|
||||
<td class="table-body-cell table-body-cell-right">
|
||||
<span class="table-cell-content">
|
||||
<% if order.stock.price_cents && order.shares %>
|
||||
<%= number_to_currency(order.purchase_cost / 100.0) %>
|
||||
<% else %>
|
||||
<span class="text-gray-600">Price unavailable</span>
|
||||
<% end %>
|
||||
</span>
|
||||
</td>
|
||||
<td class="table-body-cell table-body-cell-center">
|
||||
<div class="flex justify-center space-x-2">
|
||||
<% if order.pending? %>
|
||||
<%= link_to edit_order_path(order), class: "table-action-link", data: { turbo_frame: "modal_frame", testid: "edit-order-button" } do %>
|
||||
<i class="fa fa-pencil fa-lg"></i>
|
||||
<% end %>
|
||||
<%= form_with url: cancel_order_path(order), method: :patch, data: { confirm: t("orders.cancel.confirm"), turbo_confirm: t("orders.cancel.confirm") } do %>
|
||||
<button type="submit" class="table-action-button" title="Cancel" data-testid="cancel-order-button">
|
||||
<i class="fa fa-ban fa-lg"></i>
|
||||
</button>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<tr class="table-body-row" data-testid="no-orders">
|
||||
<td class="table-empty-cell" colspan="9">
|
||||
<p class="text-lg">No orders found</p>
|
||||
<p class="mt-2">Create your first order to get started!</p>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
<% end %>
|
||||
</main>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.array! @orders, partial: "orders/order", as: :order
|
||||
@@ -0,0 +1,5 @@
|
||||
<turbo-frame id="modal_frame">
|
||||
<div>
|
||||
<%= render "form", order: @order, transaction_type: @order.action, shares_owned: @shares_owned %>
|
||||
</div>
|
||||
</turbo-frame>
|
||||
@@ -0,0 +1,7 @@
|
||||
<%= turbo_stream.replace "modal_frame" do %>
|
||||
<turbo-frame id="modal_frame">
|
||||
<div>
|
||||
<%= render "form", order: @order, transaction_type: @order.action, shares_owned: @shares_owned %>
|
||||
</div>
|
||||
</turbo-frame>
|
||||
<% end %>
|
||||
@@ -0,0 +1,13 @@
|
||||
<p style="color: green"><%= notice %></p>
|
||||
|
||||
<%= render @order %>
|
||||
|
||||
<div>
|
||||
<% if @order.pending? %>
|
||||
<%= link_to "Edit this order", edit_order_path(@order) %> |
|
||||
<% end %>
|
||||
|
||||
<%= link_to "Back to orders", orders_path %>
|
||||
|
||||
<%= button_to "Destroy this order", @order, method: :delete %>
|
||||
</div>
|
||||
Reference in New Issue
Block a user