PageSourceSearch

https://chatexpense.com/static/expense/js/subscription.js

js chatexpense.com collected 2026-10-02 00:28:36 UTC 3,104 bytes, 67 lines download raw bytes

1import { apiGet, apiPost } from './api.js';
2
3export async function openUsageModal() {
4    const subscriptionDetails = document.getElementById('subscriptionDetails');
5    subscriptionDetails.innerHTML = '<p>Loading subscription details...</p>';
6    const userInfo = JSON.parse(localStorage.getItem('userInfo'));
7
8    if (window.fbq) {
9        fbq('trackCustom', 'SubPageVisited', {
10            user_active_plan: userInfo?.subscription?.active_plan || 'none'
11        });
12    }
13
14    try {
15        const data = await apiGet('subscription/v0/active_subscription/');
16        if (data && data.active_plan) {
17            subscriptionDetails.innerHTML = `<div class="subscription-details">
18<div class="row">
19<p><strong>Active Plan:</strong> ${data.active_plan}</p>
20<p><strong>Status:</strong> ${data.status}</p>
21</div>
22<div class="row">
23<p><strong>Start Date:</strong> ${new Date(data.start_date).toLocaleDateString()}</p>
24<p><strong>End Date:</strong> ${new Date(data.end_date).toLocaleDateString()}</p>
25</div>
26<p><strong>Image Message Usage:</strong> ${data.image_message_count}/${data.image_message_limit}</p>
27<p><strong>Text Message Usage:</strong> ${data.text_message_count}/${data.text_message_limit}</p>
28<p><strong>Voice Message Usage:</strong> ${data.voice_message_count}/${data.voice_message_limit}</p>
29<p><strong>AI Query Usage:</strong> ${data.ai_query_count}/${data.ai_query_limit}</p>
30<p><strong>Custom Category created:</strong> ${data.custom_category_count}/${data.custom_category_limit}</p>
31<p><strong>Input token usage:</strong> ${data.input_token_usage}</p>
32<p><strong>Output token usage:</strong> ${data.output_token_usage}</p>
33</div>
34<div class="text-center mt-4">
35<button id="manageSubscriptionBtn" class="btn btn-outline-danger">Manage Subscription</button>
36</div>`;
37
38            // Add click listener for Manage Subscription
39            setTimeout(() => {
40                const manageBtn = document.getElementById('manageSubscriptionBtn');
41                manageBtn?.addEventListener('click', async () => {
42                    try {
43                        const response = await apiPost('subscription/v0/cancel/', {});
44                        if (response.cancel_url) {
45                            window.location.href = response.cancel_url;
46                        } else {
47                            alert('Unable to open billing portal.');
48                        }
49                    } catch (err) {
50                        console.error('Failed to redirect to Stripe portal:', err);
51                        alert('Error redirecting to subscription management page.');
52                    }
53                });
54            }, 0);
55
56        } else {
57            subscriptionDetails.innerHTML = '<p>No subscription details available.</p>';
58        }
59    } catch (error) {
60        console.error('Error fetching subscription details:', error);
61        subscriptionDetails.innerHTML = '<p>Error loading subscription details.</p>';
62    }
63
64    // Open the modal
65    const subscriptionModal = new bootstrap.Modal(document.getElementById('subscriptionModal'));
66    subscriptionModal.show();
67}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.