Files
MySMSAPio/app/views/pages/home.html.erb
Min Zeya Phyo a5ade4006d
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
welcome page and documentatino
2026-08-01 00:27:37 +08:00

243 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- ===================== HERO ===================== -->
<section class="relative px-5 pt-20 pb-24 sm:px-8">
<div class="mx-auto max-w-5xl text-center">
<!-- Badge -->
<div class="fade-up inline-flex items-center gap-2 rounded-full glass px-4 py-1.5 text-xs">
<span class="relative flex h-2 w-2">
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-400 opacity-75"></span>
<span class="relative inline-flex h-2 w-2 rounded-full bg-sky-400"></span>
</span>
<span class="font-mono-tech uppercase tracking-[0.25em] text-slate-300">SMS Gateway · API v1</span>
</div>
<!-- Beacon logo -->
<div class="fade-up d-1 relative mx-auto mt-10 h-24 w-24 flex items-center justify-center">
<span class="beacon-ring absolute inset-0 rounded-full border border-sky-400/40"></span>
<span class="beacon-ring delay-1 absolute inset-0 rounded-full border border-sky-400/30"></span>
<span class="beacon-ring delay-2 absolute inset-0 rounded-full border border-sky-400/20"></span>
<div class="relative flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-sky-400 to-sky-600 shadow-xl shadow-sky-500/40">
<i class="fas fa-sms text-3xl text-slate-950"></i>
</div>
</div>
<h1 class="fade-up d-2 font-display mt-8 text-5xl font-extrabold tracking-tight text-white sm:text-7xl">
Send SMS through your <span class="gradient-text">Android devices</span>
</h1>
<p class="fade-up d-3 mx-auto mt-6 max-w-2xl text-lg text-slate-400 sm:text-xl">
A production-grade REST &amp; WebSocket API that turns any Android phone into a
programmable SMS gateway. Send messages, generate OTPs, receive inbound texts,
and orchestrate fleets of devices in real time.
</p>
<div class="fade-up d-4 mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
<%= link_to docs_path, class: "btn-accent inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-950" do %>
<i class="fas fa-book-open"></i> Explore the API
<% end %>
<%= link_to admin_login_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-200" do %>
<i class="fas fa-gauge-high"></i> Admin Console
<% end %>
</div>
<!-- Base URL chip -->
<div class="fade-up d-5 mx-auto mt-12 inline-flex items-center gap-3 rounded-xl glass px-5 py-3">
<span class="font-mono-tech text-[11px] uppercase tracking-wider text-slate-500">Base URL</span>
<code class="font-mono-tech text-sm text-sky-300">https://&lt;your-host&gt;/api/v1</code>
<button data-copy="https://your-host/api/v1" class="copy-btn text-slate-500 hover:text-sky-400" aria-label="Copy base URL">
<i class="far fa-copy"></i>
</button>
</div>
</div>
</section>
<!-- ===================== STAT STRIP ===================== -->
<section class="relative px-5 sm:px-8">
<div class="mx-auto max-w-5xl">
<div class="grid grid-cols-2 gap-4 rounded-2xl glass px-6 py-6 sm:grid-cols-4">
<% stats = [
{ icon: "fa-bolt", value: "< 200ms", label: "API latency" },
{ icon: "fa-infinity", value: "Unlimited", label: "Gateways" },
{ icon: "fa-shield-halved", value: "SHA-256", label: "Key hashing" },
{ icon: "fa-rotate", value: "3× retry", label: "Auto backoff" }
] %>
<% stats.each do |s| %>
<div class="flex flex-col items-center text-center">
<i class="fas <%= s[:icon] %> text-sky-400"></i>
<span class="mt-2 font-display text-xl font-bold text-white"><%= s[:value] %></span>
<span class="font-mono-tech text-[10px] uppercase tracking-[0.2em] text-slate-500"><%= s[:label] %></span>
</div>
<% end %>
</div>
</div>
</section>
<!-- ===================== FEATURES ===================== -->
<section class="relative px-5 py-24 sm:px-8">
<div class="mx-auto max-w-6xl">
<div class="mx-auto max-w-2xl text-center">
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Capabilities</p>
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Everything you need to route SMS at scale</h2>
<p class="mt-4 text-slate-400">From a single device to a distributed fleet — message queuing, delivery tracking, and OTP workflows are built in.</p>
</div>
<div class="mt-14 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
<% features = [
{ icon: "fa-paper-plane", color: "from-sky-400 to-sky-600", title: "Send SMS", desc: "Queue outbound messages and let the gateway fleet deliver them. Automatic retries with exponential backoff." },
{ icon: "fa-arrow-down", color: "from-emerald-400 to-emerald-600", title: "Receive SMS", desc: "Inbound messages land in your inbox instantly and fire webhooks so your app reacts in real time." },
{ icon: "fa-shield-halved", color: "from-violet-400 to-violet-600", title: "OTP Generation", desc: "Six-digit codes with 5-minute expiry, 3-attempt limits, and 3-per-hour rate caps per phone number." },
{ icon: "fa-plug", color: "from-amber-400 to-orange-600", title: "Webhooks", desc: "HMAC-signed event payloads for sms_received, sms_sent and sms_failed with configurable retries." },
{ icon: "fa-tower-broadcast", color: "from-pink-400 to-rose-600", title: "Realtime WebSocket", desc: "Bidirectional Action Cable channel keeps every gateway in sync — heartbeats, delivery reports, and commands." },
{ icon: "fa-mobile-screen", color: "from-blue-400 to-indigo-600", title: "Gateway Fleet", desc: "Register unlimited Android devices. Priority-based routing, health checks, and live status monitoring." }
] %>
<% features.each_with_index do |f, i| %>
<div class="fade-up d-<%= (i % 3) + 1 %> group rounded-2xl glass p-6 transition-all duration-300 hover:-translate-y-1 hover:border-sky-400/30">
<div class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br <%= f[:color] %> shadow-lg">
<i class="fas <%= f[:icon] %> text-lg text-slate-950"></i>
</div>
<h3 class="font-display mt-5 text-xl font-bold text-white"><%= f[:title] %></h3>
<p class="mt-2 text-sm leading-relaxed text-slate-400"><%= f[:desc] %></p>
</div>
<% end %>
</div>
</div>
</section>
<!-- ===================== ARCHITECTURE ===================== -->
<section class="relative px-5 py-24 sm:px-8">
<div class="mx-auto max-w-6xl">
<div class="mx-auto max-w-2xl text-center">
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Architecture</p>
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">How messages flow</h2>
<p class="mt-4 text-slate-400">A clean, asynchronous pipeline keeps the API fast and delivery resilient.</p>
</div>
<div class="mt-14 grid items-stretch gap-4 lg:grid-cols-5">
<% steps = [
{ n: "01", icon: "fa-code", title: "Client calls API", desc: "POST /api/v1/sms/send with a Bearer API key. Phone numbers are validated with Phonelib." },
{ n: "02", icon: "fa-database", title: "Message queued", desc: "SmsMessage is persisted and SendSmsJob is enqueued via Sidekiq. The API returns instantly with a message_id." },
{ n: "03", icon: "fa-route", title: "Gateway selected", desc: "SendSmsJob picks the highest-priority online, active gateway and broadcasts over Action Cable." },
{ n: "04", icon: "fa-mobile-screen-button", title: "Android delivers", desc: "The gateway device sends the SMS via its native radio and reports back a delivery status." },
{ n: "05", icon: "fa-circle-check", title: "Status & webhooks", desc: "Delivery/failed status is recorded; webhooks fire for subscribed events. Failed messages auto-retry up to 3×." }
] %>
<% steps.each do |s| %>
<div class="relative rounded-2xl glass p-6">
<span class="font-mono-tech text-xs text-sky-400/70"><%= s[:n] %></span>
<i class="fas <%= s[:icon] %> mt-3 text-2xl text-sky-400"></i>
<h3 class="font-display mt-3 text-base font-bold text-white"><%= s[:title] %></h3>
<p class="mt-2 text-xs leading-relaxed text-slate-400"><%= s[:desc] %></p>
</div>
<% end %>
</div>
</div>
</section>
<!-- ===================== QUICK START ===================== -->
<section class="relative px-5 py-24 sm:px-8">
<div class="mx-auto max-w-5xl">
<div class="text-center">
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Quick Start</p>
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Send your first message</h2>
</div>
<div class="mt-12 grid gap-6 lg:grid-cols-2">
<!-- Step 1 -->
<div class="rounded-2xl glass p-6">
<div class="flex items-center gap-3">
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">1</span>
<h3 class="font-display text-lg font-bold text-white">Register a gateway device</h3>
</div>
<p class="mt-3 text-sm text-slate-400">No auth required — receive a gateway API key back.</p>
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
<span class="tok-com"># Register your Android device</span><br>
<span class="tok-key">curl</span> -X POST https://your-host/api/v1/gateway/register \<br>
&nbsp;&nbsp;-H <span class="tok-str">"Content-Type: application/json"</span> \<br>
&nbsp;&nbsp;-d <span class="tok-str">'{"device_id":"pixel-001","name":"Office Phone"}'</span>
</div>
<div class="mt-3 flex items-center gap-2">
<button data-copy='curl -X POST https://your-host/api/v1/gateway/register -H "Content-Type: application/json" -d "{\"device_id\":\"pixel-001\",\"name\":\"Office Phone\"}"' class="copy-btn text-xs text-slate-500 hover:text-sky-400"><i class="far fa-copy"></i> Copy</button>
</div>
</div>
<!-- Step 2 -->
<div class="rounded-2xl glass p-6">
<div class="flex items-center gap-3">
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">2</span>
<h3 class="font-display text-lg font-bold text-white">Connect via WebSocket</h3>
</div>
<p class="mt-3 text-sm text-slate-400">Keep the device online and ready to receive commands.</p>
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
<span class="tok-com"># wscat</span><br>
<span class="tok-key">wscat</span> -c <span class="tok-str">"ws://your-host:3000/cable?api_key=gw_live_..."</span>
</div>
</div>
<!-- Step 3 -->
<div class="rounded-2xl glass p-6 lg:col-span-2">
<div class="flex items-center gap-3">
<span class="flex h-7 w-7 items-center justify-center rounded-full bg-sky-500 font-mono-tech text-xs font-bold text-slate-950">3</span>
<h3 class="font-display text-lg font-bold text-white">Send an SMS</h3>
</div>
<p class="mt-3 text-sm text-slate-400">Use a client API key (api_live_…) in the Authorization header.</p>
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
<span class="tok-key">curl</span> -X POST https://your-host/api/v1/sms/send \<br>
&nbsp;&nbsp;-H <span class="tok-str">"Authorization: Bearer api_live_..."</span> \<br>
&nbsp;&nbsp;-H <span class="tok-str">"Content-Type: application/json"</span> \<br>
&nbsp;&nbsp;-d <span class="tok-str">'{"to":"+14155551234","message":"Hello from MySMSAPio!"}'</span>
</div>
<div class="mt-3 flex items-center gap-2">
<button data-copy='curl -X POST https://your-host/api/v1/sms/send -H "Authorization: Bearer api_live_..." -H "Content-Type: application/json" -d "{\"to\":\"+14155551234\",\"message\":\"Hello from MySMSAPio!\"}"' class="copy-btn text-xs text-slate-500 hover:text-sky-400"><i class="far fa-copy"></i> Copy</button>
</div>
<div class="code-block mt-4 rounded-xl p-4 text-xs leading-relaxed">
<span class="tok-com"># → 202 Accepted</span><br>
{<br>
&nbsp;&nbsp;<span class="tok-key">"success"</span>: <span class="tok-bool">true</span>,<br>
&nbsp;&nbsp;<span class="tok-key">"message_id"</span>: <span class="tok-str">"msg_3f8a9c1b2e7d4f60"</span>,<br>
&nbsp;&nbsp;<span class="tok-key">"status"</span>: <span class="tok-str">"queued"</span><br>
}
</div>
</div>
</div>
<div class="mt-10 text-center">
<%= link_to docs_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-6 py-3 text-sm font-semibold text-slate-200" do %>
<i class="fas fa-arrow-right-long"></i> Read the full API reference
<% end %>
</div>
</div>
</section>
<!-- ===================== TECH STACK ===================== -->
<section class="relative px-5 py-24 sm:px-8">
<div class="mx-auto max-w-5xl">
<div class="text-center">
<p class="font-mono-tech text-[11px] uppercase tracking-[0.3em] text-sky-400/80">Built on a modern stack</p>
<h2 class="font-display mt-3 text-4xl font-bold text-white sm:text-5xl">Production-ready by default</h2>
</div>
<div class="mt-12 flex flex-wrap items-center justify-center gap-3">
<% stack = ["Rails 8.0", "Ruby 3.4", "PostgreSQL", "Redis 7", "Sidekiq 7", "Action Cable", "Puma + Thruster", "Docker / Kamal", "Tailwind CSS", "Phonelib", "HTTParty", "ROTP"] %>
<% stack.each do |tech| %>
<span class="rounded-full glass px-5 py-2 font-mono-tech text-xs text-slate-300"><%= tech %></span>
<% end %>
</div>
</div>
</section>
<!-- ===================== CTA ===================== -->
<section class="relative px-5 py-24 sm:px-8">
<div class="mx-auto max-w-4xl">
<div class="relative overflow-hidden rounded-3xl glass-strong px-8 py-16 text-center sm:px-16">
<div class="pointer-events-none absolute -top-24 left-1/2 h-64 w-64 -translate-x-1/2 rounded-full bg-sky-500/20 blur-3xl"></div>
<h2 class="font-display relative text-4xl font-bold text-white sm:text-5xl">Ready to send your first SMS?</h2>
<p class="relative mx-auto mt-4 max-w-xl text-slate-400">Dive into the complete API reference or jump straight into the admin console to manage your gateways.</p>
<div class="relative mt-8 flex flex-col items-center justify-center gap-4 sm:flex-row">
<%= link_to docs_path, class: "btn-accent inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-950" do %>
<i class="fas fa-book"></i> API Documentation
<% end %>
<%= link_to admin_login_path, class: "btn-ghost inline-flex items-center gap-2 rounded-xl px-7 py-3.5 text-base font-semibold text-slate-200" do %>
<i class="fas fa-gauge-high"></i> Open Admin Console
<% end %>
</div>
</div>
</div>
</section>