chore: init commit
in worker.../repo/GITFOLDER.zip is the .git folder.
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
<!-- Hidden checkbox for menu toggle (CSS-only, no JavaScript!) -->
|
||||
<input type="checkbox" id="mobile-menu-toggle" class="hidden peer">
|
||||
|
||||
<!-- Overlay - shows when checkbox is checked -->
|
||||
<label
|
||||
for="mobile-menu-toggle"
|
||||
class="fixed inset-0 bg-black/50 z-40 hidden peer-checked:block lg:hidden"></label>
|
||||
|
||||
<!-- Sidebar - slides in when checkbox is checked -->
|
||||
<nav class="fixed z-50 top-0 bottom-0 left-0 w-64
|
||||
transform -translate-x-full peer-checked:translate-x-0
|
||||
lg:translate-x-0 lg:top-16 lg:w-50
|
||||
transition-transform duration-300 ease-in-out">
|
||||
<div class="flex flex-col h-full overflow-y-auto px-0 pt-16 lg:pt-4 pb-4 bg-[#00698c]">
|
||||
|
||||
<!-- Close button (mobile only) -->
|
||||
<label
|
||||
for="mobile-menu-toggle"
|
||||
class="lg:hidden absolute top-4 right-4
|
||||
flex items-center justify-center w-10 h-10
|
||||
text-white hover:bg-white/10 rounded-lg
|
||||
cursor-pointer transition-colors">
|
||||
<!-- X icon -->
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
<nav class="flex flex-1 flex-col">
|
||||
<ul role="list" class="flex flex-1 flex-col gap-y-1 px-3">
|
||||
<li>
|
||||
<ul role="list" class="space-y-1">
|
||||
<!-- Home link -->
|
||||
<li>
|
||||
<% is_active = request.path == root_path %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer">
|
||||
<%= link_to root_path, class: "flex items-center justify-start px-3 py-3 rounded-lg w-full group hover:bg-black/20 #{'bg-[#d3df44]' if is_active}", style: is_active ? "background-color: #d3df44;" : "" do %>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="w-6 h-6">
|
||||
<%= image_tag "house.svg", class: "w-6 h-6", style: "filter: brightness(0) saturate(100%) #{is_active ? 'invert(20%) sepia(8%) saturate(348%) hue-rotate(114deg) brightness(98%) contrast(85%)' : 'invert(93%) sepia(13%) saturate(343%) hue-rotate(31deg) brightness(115%) contrast(90%)'};" %>
|
||||
</div>
|
||||
<span class="font-medium text-sm" style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">Home</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<!-- Portfolio link -->
|
||||
<% if current_user.portfolio && policy(current_user.portfolio).show? %>
|
||||
<li>
|
||||
<% is_active = request.path.include?('portfolios') %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer">
|
||||
<%= link_to user_portfolio_path(current_user, current_user.portfolio), class: "flex items-center justify-start px-3 py-3 rounded-lg w-full group hover:bg-black/20 #{'bg-[#d3df44]' if is_active}", style: is_active ? "background-color: #d3df44;" : "" do %>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="w-6 h-6">
|
||||
<%= image_tag "id-card.svg", class: "w-6 h-6", style: "filter: brightness(0) saturate(100%) #{is_active ? 'invert(20%) sepia(8%) saturate(348%) hue-rotate(114deg) brightness(98%) contrast(85%)' : 'invert(93%) sepia(13%) saturate(343%) hue-rotate(31deg) brightness(115%) contrast(90%)'};" %>
|
||||
</div>
|
||||
<span class="font-medium text-sm" style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">My Portfolio</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</label>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<!-- Transactions link -->
|
||||
<li>
|
||||
<% is_active = request.path.include?('orders') %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer">
|
||||
<%= link_to orders_path, class: "flex items-center justify-start px-3 py-3 rounded-lg w-full group hover:bg-black/20", style: is_active ? "background-color: #d3df44;" : "" do %>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="w-6 h-6">
|
||||
<%= image_tag "receipt.svg", class: "w-6 h-6", style: "filter: brightness(0) saturate(100%) #{is_active ? 'invert(20%) sepia(8%) saturate(348%) hue-rotate(114deg) brightness(98%) contrast(85%)' : 'invert(100%)'}" %>
|
||||
</div>
|
||||
<span class="font-medium text-sm" style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">Transactions</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<!-- Classes link -->
|
||||
<% if policy(Classroom).index? %>
|
||||
<li>
|
||||
<% is_active = request.path.include?('classrooms') && request.path.exclude?('admin') %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer">
|
||||
<%= link_to classrooms_path, class: "flex items-center justify-start px-3 py-3 rounded-lg w-full group hover:bg-black/20", style: is_active ? "background-color: #d3df44;" : "" do %>
|
||||
<div class="flex gap-3 items-center">
|
||||
<div class="w-6 h-6">
|
||||
<svg class="w-6 h-6" style="color: <%= is_active ? '#323232' : 'white' %>;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="font-medium text-sm" style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">Classes</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</label>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<!-- Trading Floor with collapsible stocks -->
|
||||
<li>
|
||||
<details <%= 'open' if request.path.include?('stocks') %> data-controller="stock-navbar-toggle">
|
||||
<summary class="flex items-center justify-between px-3 py-3 rounded-lg w-full list-none cursor-pointer <%= 'bg-[#d3df44]' if request.path.include?('stocks') %>" style="<%= request.path.include?('stocks') ? 'background-color: #d3df44;' : '' %>">
|
||||
<% is_active = request.path.include?('stocks') %>
|
||||
<%= link_to stocks_path, class: "flex gap-3 items-center flex-1 hover:opacity-80", data: { action: "click->stock-navbar-toggle#navigateLink" } do %>
|
||||
<div class="w-6 h-6">
|
||||
<%= image_tag "chart-no-axes-combined.svg", class: "w-6 h-6", style: "filter: brightness(0) saturate(100%) #{is_active ? 'invert(20%) sepia(8%) saturate(348%) hue-rotate(114deg) brightness(98%) contrast(85%)' : 'invert(100%)'}" %>
|
||||
</div>
|
||||
<span class="font-medium text-sm" style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">Trading Floor</span>
|
||||
<% end %>
|
||||
|
||||
<div class="w-4 h-4 flex items-center justify-center cursor-pointer hover:opacity-70" data-action="click->stock-navbar-toggle#toggleChevron">
|
||||
<i class="fa-solid fa-angle-down icon-down" style="color: <%= is_active ? '#323232' : 'white' %>;"></i>
|
||||
<i class="fa-solid fa-angle-up icon-up" style="color: <%= is_active ? '#323232' : 'white' %>;"></i>
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<div class="box-border content-stretch flex flex-col items-start justify-start p-2 ml-6">
|
||||
<% stocks.each do |stock| %>
|
||||
<div class="content-stretch flex items-center justify-start relative rounded-2xl w-full">
|
||||
<% stock_active = request.path == stock_path(stock) %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer w-full">
|
||||
<%= link_to stock_path(stock), class: "flex gap-2 grow min-h-[44px] items-center justify-start px-3 py-2 rounded-2xl hover:bg-black/20 w-full" do %>
|
||||
<div class="font-['Geist',sans-serif] font-normal text-sm text-white <%= 'underline decoration-2 underline-offset-2' if stock_active %>">
|
||||
<p class="leading-none"><%= stock.ticker %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</details>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Bottom section (Admin, Logout) -->
|
||||
<div class="flex flex-col items-center justify-start w-full mt-auto">
|
||||
<div class="h-px w-full bg-[#004f6b]"></div>
|
||||
<div class="flex flex-col items-start justify-start w-full py-2">
|
||||
|
||||
<% if policy(Classroom).new? %>
|
||||
<% is_active = request.path.include?('admin') %>
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer w-full">
|
||||
<%= link_to admin_classrooms_path, class: "flex items-center gap-x-4 px-6 py-3 text-sm font-semibold hover:bg-black/20 w-full", style: is_active ? "background-color: #d3df44;" : "" do %>
|
||||
<svg class="w-5 h-5" style="color: <%= is_active ? '#323232' : 'white' %>;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a6.759 6.759 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
<span style="color: <%= is_active ? '#323232' : 'white' %>; font-family: Inter, sans-serif;">Admin</span>
|
||||
<% end %>
|
||||
</label>
|
||||
<% end %>
|
||||
|
||||
<label for="mobile-menu-toggle" class="lg:cursor-default cursor-pointer w-full">
|
||||
<%= link_to destroy_user_session_path, data: { turbo_method: :delete }, class: "flex items-center gap-x-4 px-6 py-3 text-sm font-semibold hover:bg-black/20 w-full" do %>
|
||||
<svg class="w-5 h-5 text-white" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15M12 9l-3 3m0 0 3 3m-3-3h12.75" />
|
||||
</svg>
|
||||
<span class="text-white" style="font-family: Inter, sans-serif;">Logout</span>
|
||||
<% end %>
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="ticker-item">
|
||||
<div class="text-lg font-bold <%= stock.percentage_change >= 0 ? 'text-green-up' : 'text-destructive' %>">
|
||||
<%= stock.ticker.upcase %>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-1 text-xs <%= stock.percentage_change >= 0 ? 'text-green-up' : 'text-destructive' %>">
|
||||
<% if stock.percentage_change >= 0 %>
|
||||
<%= lucide_icon("trending-up", class: "w-3 h-3") %>
|
||||
<% else %>
|
||||
<%= lucide_icon("trending-down", class: "w-3 h-3") %>
|
||||
<% end %>
|
||||
<%= stock.percentage_change_formatted %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="flex-shrink-0 overflow-hidden" style="width: 400px;">
|
||||
<div class="ticker-container">
|
||||
<div class="ticker-content animate-scroll">
|
||||
<%# Duplicate stocks for seamless infinite scroll: animation moves from 0% to -50%,
|
||||
so when it reaches -50% (showing second copy), it loops back to 0% (first copy)
|
||||
creating smooth continuous scrolling without gaps or visible restarts %>
|
||||
<% (ticker_stocks.to_a * 2).each do |stock| %>
|
||||
<%= render 'layouts/stock_item', stock: stock %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="trix-content">
|
||||
<%= yield -%>
|
||||
</div>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Admin - StocksInTheFuture</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
<%= stylesheet_link_tag :app, 'data-turbo-track': "reload" %>
|
||||
<%= stylesheet_link_tag "actiontext", 'data-turbo-track': "reload" %>
|
||||
<%= javascript_importmap_tags %>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
</head>
|
||||
<body class="min-h-screen bg-gray-50" data-controller="admin-sidebar">
|
||||
<!-- Admin Header -->
|
||||
<div class="fixed top-0 left-0 w-full z-50 bg-white border-b border-gray-200">
|
||||
<div class="flex items-center justify-between py-3 px-6 h-16">
|
||||
<div class="flex items-center gap-4">
|
||||
<button
|
||||
type="button"
|
||||
data-action="click->admin-sidebar#toggle"
|
||||
class="lg:hidden inline-flex items-center justify-center w-10 h-10 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
aria-label="Toggle menu">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</button>
|
||||
<h1 class="text-xl font-semibold text-gray-900">
|
||||
<%= link_to admin_root_path do %>
|
||||
<i class="fas fa-tools text-blue-600 mr-2"></i>
|
||||
Admin Dashboard
|
||||
<% end %>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<span class="hidden sm:inline text-sm text-gray-600">
|
||||
<%= current_user.email %>
|
||||
</span>
|
||||
<%= link_to "View Site", root_path, class: "text-sm text-blue-600 hover:text-blue-800" %>
|
||||
<%= link_to "Sign Out", destroy_user_session_path, data: { turbo_method: :delete }, class: "text-sm text-red-600 hover:text-red-800" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admin Sidebar Navigation -->
|
||||
<div class="fixed top-16 left-0 h-[calc(100vh-4rem)] w-64 bg-white border-r border-gray-200 overflow-y-auto lg:block hidden" id="admin-sidebar">
|
||||
<nav class="p-4">
|
||||
<%= render "admin/shared/navigation" %>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Sidebar Overlay -->
|
||||
<div class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden"
|
||||
data-admin-sidebar-target="overlay"
|
||||
data-action="click->admin-sidebar#toggle"
|
||||
style="display: none;"></div>
|
||||
|
||||
<!-- Mobile Sidebar -->
|
||||
<div class="fixed top-16 left-0 h-[calc(100vh-4rem)] w-64 bg-white border-r border-gray-200 overflow-y-auto z-50 transform -translate-x-full transition-transform duration-300 lg:hidden"
|
||||
data-admin-sidebar-target="mobileSidebar">
|
||||
<nav class="p-4">
|
||||
<%= render "admin/shared/navigation" %>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="pt-16 lg:pl-64 min-h-screen">
|
||||
<div class="p-6">
|
||||
<!-- Flash Messages -->
|
||||
<% if notice.present? %>
|
||||
<p class="mb-4 p-4 bg-green-50 border border-green-200 text-green-800 rounded-lg" id="notice"><%= notice %></p>
|
||||
<% end %>
|
||||
<% if alert.present? %>
|
||||
<p class="mb-4 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg" id="alert"><%= alert %></p>
|
||||
<% end %>
|
||||
|
||||
<%= yield %>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>StocksInTheFuture</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
<%= stylesheet_link_tag :app, 'data-turbo-track': "reload" %>
|
||||
<%= stylesheet_link_tag "actiontext", 'data-turbo-track': "reload" %>
|
||||
<%= javascript_importmap_tags %>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
</head>
|
||||
<body class="min-h-screen bg-[#f7f9f3]">
|
||||
<% if user_signed_in? %>
|
||||
<div class="fixed top-0 left-0 w-full z-50 flex items-center justify-between py-4 px-6 h-16 bg-[#f7f9f3]">
|
||||
<div class="flex items-center gap-4">
|
||||
<label
|
||||
for="mobile-menu-toggle"
|
||||
class="lg:hidden cursor-pointer flex items-center justify-center w-10 h-10 bg-[#00698c] text-white rounded-lg hover:bg-[#004f6b] transition-colors"
|
||||
aria-label="Toggle menu">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</label>
|
||||
<%= image_tag "SITF-Horz-no-tag-logo.svg", class: "h-8 w-auto", alt: "Stocks in The Future" %>
|
||||
</div>
|
||||
<div class="hidden lg:block">
|
||||
<%= render 'layouts/stock_ticker' %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fixed w-full h-px z-40 top-16 bg-[#004f6b]"></div>
|
||||
|
||||
<%= render 'layouts/navbar', stocks: @navbar_stocks %>
|
||||
|
||||
<!-- Main: responsive margins and padding -->
|
||||
<main class="min-h-screen overflow-auto px-4 sm:px-6 ml-0 lg:ml-50 mt-16 pb-6 bg-[#f7f9f3]">
|
||||
<!-- Flash Messages -->
|
||||
<% if notice.present? %>
|
||||
<p class="mb-4 p-4 bg-green-50 border border-green-200 text-green-800 rounded-lg" id="notice"><%= notice %></p>
|
||||
<% end %>
|
||||
<% if alert.present? %>
|
||||
<p class="mb-4 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg" id="alert"><%= alert %></p>
|
||||
<% end %>
|
||||
|
||||
<%= yield %>
|
||||
</main>
|
||||
<% else %>
|
||||
<main class="min-h-screen overflow-auto p-6 bg-[#f7f9f3]">
|
||||
<%= yield %>
|
||||
</main>
|
||||
<% end %>
|
||||
|
||||
<!-- Trading Modal -->
|
||||
<%= render 'shared/modal' %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style>
|
||||
/* Email styles need to be inline */
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<%= yield %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
<%= yield %>
|
||||
Reference in New Issue
Block a user