Skip to content

Commit 51f3e66

Browse files
AchoArnoldCopilot
andcommitted
feat(web): port all pages to Nuxt 4 + Vue 3 + Vuetify 4
- Login, Index (homepage with features, pricing, FAQ) - Threads (index + [id] detail with message bubbles, Pusher real-time) - Messages (new message form) - Search Messages (search by ID/content) - Bulk Messages (file upload + history table) - Settings (API key, webhooks, discord, send schedules) - Billing (usage stats, plan upgrade) - Heartbeats, Phone API Keys - Blog (index + 7 articles) - Privacy Policy, Terms and Conditions All pages use <script setup lang=ts>, Pinia stores, useDisplay(), and Vuetify 4 component API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 018b531 commit 51f3e66

21 files changed

Lines changed: 3710 additions & 0 deletions

web/app/pages/billing/index.vue

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<script setup lang="ts">
2+
import { mdiArrowLeft, mdiCreditCard } from "@mdi/js";
3+
4+
definePageMeta({
5+
middleware: ["auth"],
6+
});
7+
8+
useHead({
9+
title: "Billing - httpSMS",
10+
});
11+
12+
const config = useRuntimeConfig();
13+
const { mdAndDown, lgAndUp } = useDisplay();
14+
const authStore = useAuthStore();
15+
const billingStore = useBillingStore();
16+
const notificationsStore = useNotificationsStore();
17+
const { useApi } = useApiComposable();
18+
19+
const loading = ref(true);
20+
const usage = ref<any>(null);
21+
22+
async function loadBillingUsage() {
23+
loading.value = true;
24+
try {
25+
const api = useApi();
26+
const response = await api<{ data: any }>("/v1/billing/usage");
27+
usage.value = response.data;
28+
} catch {
29+
// silently fail
30+
} finally {
31+
loading.value = false;
32+
}
33+
}
34+
35+
function getCheckoutUrl() {
36+
window.open(config.public.checkoutUrl as string, "_blank");
37+
}
38+
39+
function getEnterpriseCheckoutUrl() {
40+
window.open(config.public.enterpriseCheckoutUrl as string, "_blank");
41+
}
42+
43+
onMounted(async () => {
44+
await authStore.loadUser();
45+
await loadBillingUsage();
46+
});
47+
</script>
48+
49+
<template>
50+
<VContainer fluid class="px-0 pt-0" :class="{ 'fill-height': lgAndUp }">
51+
<div class="w-100 h-100">
52+
<VAppBar height="60" :density="mdAndDown ? 'compact' : 'default'">
53+
<VBtn icon to="/threads">
54+
<VIcon :icon="mdiArrowLeft" />
55+
</VBtn>
56+
<VToolbarTitle>Billing</VToolbarTitle>
57+
</VAppBar>
58+
<VContainer class="mt-16">
59+
<VRow>
60+
<VCol cols="12" md="8" offset-md="2">
61+
<h4 class="text-h4 mb-3">Usage</h4>
62+
<p class="text-medium-emphasis">
63+
Your current billing period usage and limits.
64+
</p>
65+
66+
<VProgressLinear v-if="loading" indeterminate class="mb-4" />
67+
68+
<template v-else-if="usage">
69+
<VCard class="mb-6">
70+
<VCardText>
71+
<VRow>
72+
<VCol cols="6" md="3">
73+
<div class="text-center">
74+
<p class="text-h4 text-primary">
75+
{{ usage.sent_messages ?? 0 }}
76+
</p>
77+
<p class="text-medium-emphasis text-subtitle-2">
78+
Messages Sent
79+
</p>
80+
</div>
81+
</VCol>
82+
<VCol cols="6" md="3">
83+
<div class="text-center">
84+
<p class="text-h4 text-primary">
85+
{{ usage.received_messages ?? 0 }}
86+
</p>
87+
<p class="text-medium-emphasis text-subtitle-2">
88+
Messages Received
89+
</p>
90+
</div>
91+
</VCol>
92+
<VCol cols="6" md="3">
93+
<div class="text-center">
94+
<p class="text-h4">{{ usage.total_messages ?? 0 }}</p>
95+
<p class="text-medium-emphasis text-subtitle-2">
96+
Total Messages
97+
</p>
98+
</div>
99+
</VCol>
100+
<VCol cols="6" md="3">
101+
<div class="text-center">
102+
<p class="text-h4">{{ usage.message_limit ?? 200 }}</p>
103+
<p class="text-medium-emphasis text-subtitle-2">
104+
Monthly Limit
105+
</p>
106+
</div>
107+
</VCol>
108+
</VRow>
109+
<VProgressLinear
110+
:model-value="
111+
((usage.total_messages ?? 0) /
112+
(usage.message_limit ?? 200)) *
113+
100
114+
"
115+
color="primary"
116+
height="8"
117+
rounded
118+
class="mt-4"
119+
/>
120+
</VCardText>
121+
</VCard>
122+
123+
<h4 class="text-h4 mb-3 mt-8">Upgrade Plan</h4>
124+
<p class="text-medium-emphasis mb-4">
125+
Upgrade your plan to send and receive more SMS messages per
126+
month.
127+
</p>
128+
129+
<VRow>
130+
<VCol cols="12" md="6">
131+
<VCard>
132+
<VCardTitle>Pro Plan</VCardTitle>
133+
<VCardSubtitle>Up to 5,000 messages/month</VCardSubtitle>
134+
<VCardText>
135+
<p class="text-h4 text-primary mb-2">
136+
$10<span class="text-body-1">/month</span>
137+
</p>
138+
<ul class="ml-4">
139+
<li>5,000 SMS messages per month</li>
140+
<li>Priority support</li>
141+
<li>Webhook integrations</li>
142+
</ul>
143+
</VCardText>
144+
<VCardActions>
145+
<VBtn color="primary" block @click="getCheckoutUrl">
146+
<VIcon start :icon="mdiCreditCard" />
147+
Upgrade to Pro
148+
</VBtn>
149+
</VCardActions>
150+
</VCard>
151+
</VCol>
152+
<VCol cols="12" md="6">
153+
<VCard>
154+
<VCardTitle>Enterprise Plan</VCardTitle>
155+
<VCardSubtitle>Custom message limits</VCardSubtitle>
156+
<VCardText>
157+
<p class="text-h4 mb-2">Custom</p>
158+
<ul class="ml-4">
159+
<li>Up to 200,000+ SMS messages per month</li>
160+
<li>Dedicated support</li>
161+
<li>Custom integrations</li>
162+
</ul>
163+
</VCardText>
164+
<VCardActions>
165+
<VBtn
166+
color="secondary"
167+
block
168+
@click="getEnterpriseCheckoutUrl"
169+
>
170+
Contact Sales
171+
</VBtn>
172+
</VCardActions>
173+
</VCard>
174+
</VCol>
175+
</VRow>
176+
</template>
177+
</VCol>
178+
</VRow>
179+
</VContainer>
180+
</div>
181+
</VContainer>
182+
</template>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<script setup lang="ts">
2+
definePageMeta({ layout: "website" });
3+
useHead({
4+
title: "How to Add End-to-End Encryption to SMS Messages - httpSMS",
5+
});
6+
</script>
7+
8+
<template>
9+
<VContainer>
10+
<VRow>
11+
<VCol cols="12" md="8" offset-md="2">
12+
<h1 class="text-h3 mb-2">
13+
How to Add End-to-End Encryption to SMS Messages
14+
</h1>
15+
<BlogInfo date="September 15, 2023" read-time="5 min read" />
16+
<VDivider class="my-6" />
17+
<p class="text-body-1 mb-4">
18+
Privacy is fundamental. With httpSMS, you can add end-to-end
19+
encryption to your SMS messages using military-grade AES-256
20+
encryption. This ensures that only you and the intended recipient can
21+
read the message content.
22+
</p>
23+
<h2 class="text-h5 mt-6 mb-3">How It Works</h2>
24+
<p class="text-body-1 mb-4">
25+
When you enable encryption in the httpSMS Android app, all messages
26+
are encrypted before being sent. The encryption key is derived from a
27+
passphrase that you set in the app settings. Both sender and receiver
28+
must use the same passphrase.
29+
</p>
30+
<h2 class="text-h5 mt-6 mb-3">Setup Steps</h2>
31+
<ol class="ml-6 mb-4">
32+
<li class="mb-2">Open the httpSMS app on your Android phone</li>
33+
<li class="mb-2">Go to Settings → Encryption</li>
34+
<li class="mb-2">Enable encryption and set your passphrase</li>
35+
<li class="mb-2">Share the passphrase securely with the recipient</li>
36+
<li class="mb-2">
37+
The recipient enables encryption with the same passphrase
38+
</li>
39+
</ol>
40+
<p class="text-body-1 mb-4">
41+
Messages are encrypted using AES-256 in CFB mode with a SHA-256
42+
derived key. The encryption happens on-device before the message is
43+
sent to the httpSMS API.
44+
</p>
45+
<BlogAuthorBio />
46+
</VCol>
47+
</VRow>
48+
</VContainer>
49+
</template>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup lang="ts">
2+
definePageMeta({ layout: "website" });
3+
useHead({ title: "Forward Incoming SMS from Phone to Webhook - httpSMS" });
4+
</script>
5+
6+
<template>
7+
<VContainer>
8+
<VRow>
9+
<VCol cols="12" md="8" offset-md="2">
10+
<h1 class="text-h3 mb-2">Forward Incoming SMS from Phone to Webhook</h1>
11+
<BlogInfo date="August 20, 2023" read-time="4 min read" />
12+
<VDivider class="my-6" />
13+
<p class="text-body-1 mb-4">
14+
Configure httpSMS to automatically forward incoming SMS messages to
15+
your server via webhooks. This allows you to build powerful automation
16+
workflows.
17+
</p>
18+
<h2 class="text-h5 mt-6 mb-3">Setting Up a Webhook</h2>
19+
<ol class="ml-6 mb-4">
20+
<li class="mb-2">Log in to your httpSMS dashboard</li>
21+
<li class="mb-2">Navigate to Settings → Webhooks</li>
22+
<li class="mb-2">Click "Add Webhook"</li>
23+
<li class="mb-2">Enter your server's callback URL</li>
24+
<li class="mb-2">Select the "message.phone.received" event</li>
25+
<li class="mb-2">Save the webhook</li>
26+
</ol>
27+
<p class="text-body-1 mb-4">
28+
When an SMS is received on your phone, httpSMS will send a POST
29+
request to your callback URL with the message details in JSON format.
30+
</p>
31+
<BlogAuthorBio />
32+
</VCol>
33+
</VRow>
34+
</VContainer>
35+
</template>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script setup lang="ts">
2+
definePageMeta({ layout: "website" });
3+
useHead({ title: "Grant Send and Read SMS Permissions on Android - httpSMS" });
4+
</script>
5+
6+
<template>
7+
<VContainer>
8+
<VRow>
9+
<VCol cols="12" md="8" offset-md="2">
10+
<h1 class="text-h3 mb-2">
11+
Grant Send and Read SMS Permissions on Android
12+
</h1>
13+
<BlogInfo date="July 10, 2023" read-time="3 min read" />
14+
<VDivider class="my-6" />
15+
<p class="text-body-1 mb-4">
16+
The httpSMS Android app requires certain permissions to send and
17+
receive SMS messages. This guide walks you through granting the
18+
necessary permissions.
19+
</p>
20+
<h2 class="text-h5 mt-6 mb-3">Required Permissions</h2>
21+
<ul class="ml-6 mb-4">
22+
<li class="mb-2">
23+
<strong>SEND_SMS</strong> - Required to send SMS messages
24+
</li>
25+
<li class="mb-2">
26+
<strong>READ_SMS</strong> - Required to read incoming messages
27+
</li>
28+
<li class="mb-2">
29+
<strong>RECEIVE_SMS</strong> - Required to detect new messages
30+
</li>
31+
</ul>
32+
<h2 class="text-h5 mt-6 mb-3">How to Grant Permissions</h2>
33+
<ol class="ml-6 mb-4">
34+
<li class="mb-2">Open the httpSMS app</li>
35+
<li class="mb-2">When prompted, tap "Allow" for each permission</li>
36+
<li class="mb-2">
37+
If you denied earlier, go to Settings → Apps → httpSMS → Permissions
38+
</li>
39+
<li class="mb-2">Enable SMS permissions</li>
40+
</ol>
41+
<BlogAuthorBio />
42+
</VCol>
43+
</VRow>
44+
</VContainer>
45+
</template>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script setup lang="ts">
2+
definePageMeta({ layout: "website" });
3+
useHead({ title: "How to Send SMS Messages from Excel - httpSMS" });
4+
</script>
5+
6+
<template>
7+
<VContainer>
8+
<VRow>
9+
<VCol cols="12" md="8" offset-md="2">
10+
<h1 class="text-h3 mb-2">How to Send SMS Messages from Excel</h1>
11+
<BlogInfo date="June 5, 2023" read-time="4 min read" />
12+
<VDivider class="my-6" />
13+
<p class="text-body-1 mb-4">
14+
Send bulk SMS messages to multiple recipients using a simple Excel
15+
template. No coding required!
16+
</p>
17+
<h2 class="text-h5 mt-6 mb-3">Steps</h2>
18+
<ol class="ml-6 mb-4">
19+
<li class="mb-2">
20+
Download the
21+
<a href="/templates/httpsms-bulk.xlsx">Excel template</a>
22+
</li>
23+
<li class="mb-2">Fill in the phone numbers and messages</li>
24+
<li class="mb-2">Go to Bulk Messages in your httpSMS dashboard</li>
25+
<li class="mb-2">Upload the file and click Send</li>
26+
</ol>
27+
<p class="text-body-1 mb-4">
28+
The template has two columns: "to" (phone number in international
29+
format) and "content" (the message text). You can send to up to 1,000
30+
recipients per file.
31+
</p>
32+
<BlogAuthorBio />
33+
</VCol>
34+
</VRow>
35+
</VContainer>
36+
</template>

0 commit comments

Comments
 (0)