Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
harishmohanraj committed Nov 29, 2023
1 parent 0fa539f commit dcd1e08
Show file tree
Hide file tree
Showing 13 changed files with 611 additions and 499 deletions.
44 changes: 24 additions & 20 deletions main.wasp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ app chatApp {
("stripe", "11.15.0"),
("markdown-to-jsx", "7.3.2"),
],
webSocket: {
fn: import { webSocketFn } from "@server/webSocket.js"
},
// webSocket: {
// fn: import { webSocketFn } from "@server/webSocket.js"
// },
}

/* 💽 Wasp defines DB entities via Prisma Database Models:
Expand Down Expand Up @@ -128,15 +128,25 @@ entity Chat {=psl
psl=}

entity Conversation {=psl
id Int @id @default(autoincrement())
conversation Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
status String?
chat Chat? @relation(fields: [chatId], references: [id])
chatId Int?
user User? @relation(fields: [userId], references: [id])
userId Int?
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
message String
role String
type String?
team_id Int?
team_name String?
team_status String?
replyToConversationId Int?
replyToConversation Conversation? @relation("replyToConversation", fields: [replyToConversationId], references: [id])
replyToConversationRecord Conversation[] @relation("replyToConversation")
previousConversationId Int?
previousConversation Conversation? @relation("previousConversation", fields: [previousConversationId], references: [id])
previousConversationRecord Conversation[] @relation("previousConversation")
chat Chat? @relation(fields: [chatId], references: [id])
chatId Int?
user User? @relation(fields: [userId], references: [id])
userId Int?
psl=}


Expand Down Expand Up @@ -208,12 +218,6 @@ page ChatPage {

// 📝 Actions aka Mutations

action generateGptResponse {
fn: import { generateGptResponse } from "@server/actions.js",
// entities: [User, RelatedObject]
entities: [User]
}

action stripePayment {
fn: import { stripePayment } from "@server/actions.js",
entities: [User]
Expand All @@ -224,8 +228,8 @@ action createChat {
entities: [Chat, Conversation]
}

action updateConversation {
fn: import { updateConversation } from "@server/actions.js",
action addNewConversationToChat {
fn: import { addNewConversationToChat } from "@server/actions.js",
entities: [Chat, Conversation]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Warnings:
- You are about to drop the column `conversation` on the `Conversation` table. All the data in the column will be lost.
- You are about to drop the column `status` on the `Conversation` table. All the data in the column will be lost.
- Added the required column `message` to the `Conversation` table without a default value. This is not possible if the table is not empty.
- Added the required column `role` to the `Conversation` table without a default value. This is not possible if the table is not empty.
- Added the required column `type` to the `Conversation` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Conversation" DROP COLUMN "conversation",
DROP COLUMN "status",
ADD COLUMN "message" TEXT NOT NULL,
ADD COLUMN "previousConversationId" INTEGER,
ADD COLUMN "replyToConversationId" INTEGER,
ADD COLUMN "role" TEXT NOT NULL,
ADD COLUMN "team_id" INTEGER,
ADD COLUMN "team_name" TEXT,
ADD COLUMN "team_status" TEXT,
ADD COLUMN "type" TEXT NOT NULL;

-- AddForeignKey
ALTER TABLE "Conversation" ADD CONSTRAINT "Conversation_replyToConversationId_fkey" FOREIGN KEY ("replyToConversationId") REFERENCES "Conversation"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Conversation" ADD CONSTRAINT "Conversation_previousConversationId_fkey" FOREIGN KEY ("previousConversationId") REFERENCES "Conversation"("id") ON DELETE SET NULL ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Conversation" ALTER COLUMN "type" DROP NOT NULL;
90 changes: 59 additions & 31 deletions src/client/AccountPage.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
import { User } from '@wasp/entities';
import { useQuery } from '@wasp/queries'
import { User } from "@wasp/entities";
import { useQuery } from "@wasp/queries";
// import getRelatedObjects from '@wasp/queries/getRelatedObjects'
import logout from '@wasp/auth/logout';
import stripePayment from '@wasp/actions/stripePayment';
import { useState, Dispatch, SetStateAction } from 'react';
import logout from "@wasp/auth/logout";
import stripePayment from "@wasp/actions/stripePayment";
import { useState, Dispatch, SetStateAction } from "react";

// get your own link from your stripe dashboard: https://dashboard.stripe.com/settings/billing/portal
const CUSTOMER_PORTAL_LINK = 'https://billing.stripe.com/p/login/test_8wM8x17JN7DT4zC000';
const CUSTOMER_PORTAL_LINK =
"https://billing.stripe.com/p/login/test_8wM8x17JN7DT4zC000";

export default function Example({ user }: { user: User }) {
const [isLoading, setIsLoading] = useState<boolean>(false);

// const { data: relatedObjects, isLoading: isLoadingRelatedObjects } = useQuery(getRelatedObjects)

return (
<div className='mt-10 px-6 mx-auto w-auto md:w-1/2'>
<div className='overflow-hidden bg-white ring-1 ring-gray-900/10 shadow-lg sm:rounded-lg m-8 '>
<div className='px-4 py-5 sm:px-6 lg:px-8'>
<h3 className='text-base font-semibold leading-6 text-gray-900'>Account Information</h3>
<div className="mt-10 px-6 mx-auto w-auto md:w-1/2">
<div className="overflow-hidden bg-white ring-1 ring-gray-900/10 shadow-lg sm:rounded-lg m-8 ">
<div className="px-4 py-5 sm:px-6 lg:px-8">
<h3 className="text-base font-semibold leading-6 text-gray-900">
Account Information
</h3>
</div>
<div className='border-t border-gray-200 px-4 py-5 sm:p-0'>
<dl className='sm:divide-y sm:divide-gray-200'>
<div className='py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6'>
<dt className='text-sm font-medium text-gray-500'>Email address</dt>
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>{user.email}</dd>
<div className="border-t border-gray-200 px-4 py-5 sm:p-0">
<dl className="sm:divide-y sm:divide-gray-200">
<div className="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
Email address
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
{user.email}
</dd>
</div>
{/* <div className='py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6'>
<dt className='text-sm font-medium text-gray-500'>Your Plan</dt>
Expand All @@ -46,8 +53,8 @@ export default function Example({ user }: { user: User }) {
<dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>I'm a cool customer.</dd>
</div> */}
{/* <div className='py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6'> */}
{/* <dt className='text-sm font-medium text-gray-500'>Most Recent User RelatedObject</dt> */}
{/* <dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
{/* <dt className='text-sm font-medium text-gray-500'>Most Recent User RelatedObject</dt> */}
{/* <dd className='mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0'>
{!!relatedObjects && relatedObjects.length > 0
? relatedObjects[relatedObjects.length - 1].content
: "You don't have any at this time."}
Expand All @@ -56,10 +63,10 @@ export default function Example({ user }: { user: User }) {
</dl>
</div>
</div>
<div className='inline-flex w-full justify-end'>
<div className="inline-flex w-full justify-end">
<button
onClick={logout}
className='inline-flex justify-center mx-8 py-2 px-4 border border-transparent shadow-md text-sm font-medium rounded-md text-white bg-captn-cta-red hover:bg-captn-cta-red-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
className="inline-flex justify-center mx-8 py-2 px-4 border border-transparent shadow-md text-sm font-medium rounded-md text-white bg-captn-cta-red hover:bg-captn-cta-red-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
logout
</button>
Expand All @@ -68,42 +75,63 @@ export default function Example({ user }: { user: User }) {
);
}

function BuyMoreButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsLoading: Dispatch<SetStateAction<boolean>> }) {
function BuyMoreButton({
isLoading,
setIsLoading,
}: {
isLoading: boolean;
setIsLoading: Dispatch<SetStateAction<boolean>>;
}) {
const handleClick = async () => {
try {
setIsLoading(true);
const stripeResults = await stripePayment();
if (stripeResults?.sessionUrl) {
window.open(stripeResults.sessionUrl, '_self');
window.open(stripeResults.sessionUrl, "_self");
}

} catch (error: any) {
alert(error?.message ?? 'Something went wrong.')
alert(error?.message ?? "Something went wrong.");
} finally {
setIsLoading(false);
}
};

return (
<div className='ml-4 flex-shrink-0 sm:col-span-1 sm:mt-0'>
<button onClick={handleClick} className={`font-medium text-sm text-indigo-600 hover:text-indigo-500 ${isLoading && 'animate-pulse'}`}>
{!isLoading ? 'Buy More/Upgrade' : 'Loading...'}
<div className="ml-4 flex-shrink-0 sm:col-span-1 sm:mt-0">
<button
onClick={handleClick}
className={`font-medium text-sm text-indigo-600 hover:text-indigo-500 ${
isLoading && "animate-pulse"
}`}
>
{!isLoading ? "Buy More/Upgrade" : "Loading..."}
</button>
</div>
);
}

function CustomerPortalButton({ isLoading, setIsLoading }: { isLoading: boolean, setIsLoading: Dispatch<SetStateAction<boolean>> }) {
function CustomerPortalButton({
isLoading,
setIsLoading,
}: {
isLoading: boolean;
setIsLoading: Dispatch<SetStateAction<boolean>>;
}) {
const handleClick = () => {
setIsLoading(true);
window.open(CUSTOMER_PORTAL_LINK, '_blank');
window.open(CUSTOMER_PORTAL_LINK, "_blank");
setIsLoading(false);
};

return (
<div className='ml-4 flex-shrink-0 sm:col-span-1 sm:mt-0'>
<button onClick={handleClick} className={`font-medium text-sm text-indigo-600 hover:text-indigo-500 ${isLoading && 'animate-pulse'}`}>
{!isLoading ? 'Manage Subscription' : 'Loading...'}
<div className="ml-4 flex-shrink-0 sm:col-span-1 sm:mt-0">
<button
onClick={handleClick}
className={`font-medium text-sm text-indigo-600 hover:text-indigo-500 ${
isLoading && "animate-pulse"
}`}
>
{!isLoading ? "Manage Subscription" : "Loading..."}
</button>
</div>
);
Expand Down
81 changes: 49 additions & 32 deletions src/client/PricingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { AiOutlineCheck } from 'react-icons/ai';
import stripePayment from '@wasp/actions/stripePayment';
import { useState } from 'react';
import { AiOutlineCheck } from "react-icons/ai";
import stripePayment from "@wasp/actions/stripePayment";
import { useState } from "react";

const prices = [
{
name: 'Credits',
id: 'credits',
href: '',
price: '$2.95',
description: 'Buy credits to use for your projects.',
features: ['10 credits', 'Use them any time', 'No expiration date'],
name: "Credits",
id: "credits",
href: "",
price: "$2.95",
description: "Buy credits to use for your projects.",
features: ["10 credits", "Use them any time", "No expiration date"],
disabled: true,
},
{
name: 'Monthly Subscription',
id: 'monthly',
href: '#',
priceMonthly: '$9.99',
description: 'Get unlimited usage for your projects.',
features: ['Unlimited usage of all features', 'Priority support', 'Cancel any time'],
name: "Monthly Subscription",
id: "monthly",
href: "#",
priceMonthly: "$9.99",
description: "Get unlimited usage for your projects.",
features: [
"Unlimited usage of all features",
"Priority support",
"Cancel any time",
],
},
];

Expand All @@ -30,43 +34,55 @@ export default function PricingPage() {
try {
const response = await stripePayment();
if (response?.sessionUrl) {
window.open(response.sessionUrl, '_self');
window.open(response.sessionUrl, "_self");
}
} catch (e) {
alert('Something went wrong. Please try again.');
alert("Something went wrong. Please try again.");
console.error(e);
} finally {
setIsLoading(false);
}
};


return (
<div className='mt-10 pb-24 sm:pb-32'>
<div className='mx-auto max-w-7xl px-6 lg:px-8'>
<div className='mx-auto grid max-w-md grid-cols-1 gap-8 lg:max-w-4xl lg:grid-cols-2'>
<div className="mt-10 pb-24 sm:pb-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto grid max-w-md grid-cols-1 gap-8 lg:max-w-4xl lg:grid-cols-2">
{prices.map((price) => (
<div
key={price.id}
className='flex flex-col justify-between rounded-3xl bg-white p-8 shadow-xl ring-1 ring-gray-900/10 sm:p-10'
className="flex flex-col justify-between rounded-3xl bg-white p-8 shadow-xl ring-1 ring-gray-900/10 sm:p-10"
>
<div>
<h3 id={price.id} className='text-base font-semibold leading-7 text-indigo-600'>
<h3
id={price.id}
className="text-base font-semibold leading-7 text-indigo-600"
>
{price.name}
</h3>
<div className='mt-4 flex items-baseline gap-x-2'>
<span className='text-5xl font-bold tracking-tight text-gray-900'>
<div className="mt-4 flex items-baseline gap-x-2">
<span className="text-5xl font-bold tracking-tight text-gray-900">
{price.priceMonthly || price.price}
</span>
{price.priceMonthly && (
<span className='text-base font-semibold leading-7 text-gray-600'>/month</span>
<span className="text-base font-semibold leading-7 text-gray-600">
/month
</span>
)}
</div>
<p className='mt-6 text-base leading-7 text-gray-600'>{price.description}</p>
<ul role='list' className='mt-10 space-y-4 text-sm leading-6 text-gray-600'>
<p className="mt-6 text-base leading-7 text-gray-600">
{price.description}
</p>
<ul
role="list"
className="mt-10 space-y-4 text-sm leading-6 text-gray-600"
>
{price.features.map((feature) => (
<li key={feature} className='flex gap-x-3'>
<AiOutlineCheck className='h-6 w-5 flex-none text-indigo-600' aria-hidden='true' />
<li key={feature} className="flex gap-x-3">
<AiOutlineCheck
className="h-6 w-5 flex-none text-indigo-600"
aria-hidden="true"
/>
{feature}
</li>
))}
Expand All @@ -77,10 +93,11 @@ export default function PricingPage() {
aria-describedby={price.id}
disabled={price.disabled}
className={`${
price.disabled && 'disabled:opacity-25 disabled:cursor-not-allowed'
price.disabled &&
"disabled:opacity-25 disabled:cursor-not-allowed"
} mt-8 block rounded-md bg-yellow-400 px-3.5 py-2 text-center text-sm font-semibold leading-6 text-black shadow-sm hover:bg-yellow-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-yellow-600`}
>
{isLoading ? 'Loading...' : 'Buy Now'}
{isLoading ? "Loading..." : "Buy Now"}
</button>
</div>
))}
Expand Down
Loading

0 comments on commit dcd1e08

Please sign in to comment.