Skip to content

Commit

Permalink
refactor: Implement lazy loading for images in DashboardV2 and update…
Browse files Browse the repository at this point in the history
… chat route
  • Loading branch information
Arghya721 committed Jul 6, 2024
1 parent 59c4551 commit 9b13ca9
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 8 deletions.
32 changes: 30 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import razorpay
from razorpay.resources.subscription import Subscription
from razorpay.resources.customer import Customer
from razorpay.resources.plan import Plan


dotenv.load_dotenv()
Expand Down Expand Up @@ -134,6 +135,9 @@ class ChatByIdHistory(BaseModel):
regenerate_message: bool
model: str

class SubscriptionRequest(BaseModel):
redirect_url: str

model_company_mapping = {
"gpt-3.5-turbo": ChatOpenAI,
"gpt-4-turbo-preview": ChatOpenAI,
Expand Down Expand Up @@ -590,11 +594,12 @@ async def chat_by_id(chat_id: str, token_info: dict = Depends(verify_token)):
logging.error("Error processing chat request: %s", e)
raise HTTPException(status_code=500, detail="Internal server error") from e

@app.get("/v1/subscriptions", tags=["Subscription Endpoints"])
async def get_subscriptions(token_info: dict = Depends(verify_token)):
@app.post("/v1/subscriptions", tags=["Subscription Endpoints"])
async def get_subscriptions(request: SubscriptionRequest, token_info: dict = Depends(verify_token)):
"""Get the subscriptions for the user."""
# create a subscription object using customer id as token_info['sub'] and plan id as PLAN_ID
try:

# check if customer id exists in the database
customer_ref = db.collection('users').document(token_info['sub'])
customer_data = customer_ref.get()
Expand All @@ -607,6 +612,9 @@ async def get_subscriptions(token_info: dict = Depends(verify_token)):
"notify_info" : {
"notify_email" : customer_data.to_dict()['email']
},
"notes": {
"redirect_url": request.redirect_url
},
# make expire_by 10 mins from now
"expire_by" : int(datetime.datetime.now().timestamp()) + 600

Expand Down Expand Up @@ -669,6 +677,26 @@ async def get_subscription_status(subscription_id: str, token_info: dict = Depen
logging.error("Error getting subscription status: %s", e)
raise HTTPException(status_code=500, detail="Internal server error") from e

@app.get("/v1/plans", tags=["Subscription Endpoints"])
async def get_plans(token_info: dict = Depends(verify_token)):
"""Get the plans for the user."""
try:
# fetch the plan details using PLAN_ID
plan = Plan(client).fetch(PLAN_ID)
# convert plan amount to float by dividing by 100
amount = plan['item']['amount'] / 100

plan_response = {
"plan_id": plan['id'],
"name": plan['item']['name'],
"amount": amount,
"currency": plan['item']['currency'],
}
return plan_response
except Exception as e:
logging.error("Error getting plans: %s", e)
raise HTTPException(status_code=500, detail="Internal server error") from e


if __name__ == "__main__":
import uvicorn
Expand Down
107 changes: 101 additions & 6 deletions web/src/components/PlansModal.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,91 @@
import React from "react";
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from "@nextui-org/react";
import React, { useEffect, useState } from "react";
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, Spinner } from "@nextui-org/react";
import axios from "axios";

export const PlansModal = ({ isOpen, onClose }) => {
const API_HOST = process.env.REACT_APP_API_HOST || "http://localhost:5000";
const accessToken = localStorage.getItem("accessToken");

const [plans, setPlans] = useState();
const [loading, setLoading] = useState(false);

const createSubscription = async () => {
setLoading(true);
try {
const redirectUrl = window.location.href;

const response = await axios.post(
`${API_HOST}/v1/subscriptions`,
{
"redirect_url": redirectUrl,
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);

if (response.data && response.data.short_url) {
// Open the payment URL in a popup
const paymentPopup = window.open(
response.data.short_url,
'RazorpayPayment',
'width=600,height=600,resizable=yes,scrollbars=yes,status=yes'
);

// Check if popup was blocked by the browser
if (!paymentPopup || paymentPopup.closed || typeof paymentPopup.closed == 'undefined') {
alert("Popup blocked. Please allow popups for this site to proceed with the payment.");
}

// Listen for messages from the popup
window.addEventListener('message', handlePaymentMessage, false);
} else {
console.error('No payment URL received');
}
} catch (error) {
console.error('Error creating subscription:', error);
} finally {
setLoading(false);
}
};

const handlePaymentMessage = (event) => {
// Verify the origin of the message
if (event.origin !== window.location.origin) return;

if (event.data.paymentStatus === 'success') {
// Handle successful payment
console.log('Payment successful');
onClose(); // Close the modal
// You might want to update the user's subscription status here
} else if (event.data.paymentStatus === 'failure') {
// Handle payment failure
console.log('Payment failed');
}

// Remove the event listener
window.removeEventListener('message', handlePaymentMessage);
};

useEffect(() => {
const fetchPlans = async () => {
try {
const response = await axios.get(`${API_HOST}/v1/plans`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
setPlans(response.data);
} catch (error) {
console.error('Error fetching plans:', error);
}
};

fetchPlans();
}, [API_HOST, accessToken]);

export const PlansModal = ({ isOpen, onClose, dark }) => {
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalContent className={`bg-white dark:bg-gray-900 dark:text-white rounded-lg shadow-lg p-6`}>
Expand All @@ -12,7 +96,7 @@ export const PlansModal = ({ isOpen, onClose, dark }) => {
<div className="flex flex-col space-y-4">
<div className="flex items-center justify-between">
<span className={`text-lg font-semibold dark:text-gray-300 text-gray-700`}>Price:</span>
<span className="text-xl font-bold text-green-500">1650</span>
<span className="text-xl font-bold text-green-500">{plans?.amount}</span>
</div>
<div className="flex items-center space-x-2">
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
Expand All @@ -29,8 +113,19 @@ export const PlansModal = ({ isOpen, onClose, dark }) => {
</div>
</ModalBody>
<ModalFooter>
<Button className={`dark:bg-green-600 dark:hover:bg-green-700 bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded`} onClick={onClose}>
Subscribe Now
<Button
className={`dark:bg-green-600 dark:hover:bg-green-700 bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded`}
onClick={createSubscription}
disabled={loading}
>
{loading ? (
<>
<Spinner size="sm" color="white" />
<span className="ml-2">Processing...</span>
</>
) : (
'Subscribe Now'
)}
</Button>
</ModalFooter>
</ModalContent>
Expand Down

0 comments on commit 9b13ca9

Please sign in to comment.