Skip to content

Commit

Permalink
lesog
Browse files Browse the repository at this point in the history
  • Loading branch information
JUNIORCO committed Sep 6, 2024
1 parent 5182e24 commit 72681fe
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 27 deletions.
2 changes: 1 addition & 1 deletion app/actions/create-pyng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ For example, a user can set up "email <> when <a new blog post is release> for <

console.log("runId: ", runId);

const maxAttempts = 10;
const maxAttempts = 30;
const pollInterval = 1000;

for (let attempt = 0; attempt < maxAttempts; attempt++) {
Expand Down
2 changes: 1 addition & 1 deletion app/components/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const UserProfile = ({ user }: { user: UserResource }) => {
};

return (
<div className="dropdown dropdown-bottom dropdown-end">
<div className="dropdown dropdown-bottom dropdown-start md:dropdown-end">
<div tabIndex={0} role="button" className="avatar">
<div className="w-10 rounded-full">
<img src={clerk.user?.imageUrl} alt="User avatar" />
Expand Down
10 changes: 9 additions & 1 deletion app/components/create-pyng/create-pyng-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export default function CreatePyngForm({
const disabled = isSubmitting;

const onSubmit: SubmitHandler<IFormInput> = async (data) => {
console.log("clerkUserId inside", data);
if (!clerkUserId) {
toast.success(
<p>
Expand All @@ -57,6 +56,11 @@ export default function CreatePyngForm({
return;
}

toast.success("Hold on, this could take 10 seconds.", {
icon: "⏳",
duration: 3500,
});

const result = await createPyng(data);
if (!result.success || result.error) {
toast.error("Sorry, something went wrong. Please try again", {
Expand Down Expand Up @@ -113,6 +117,10 @@ export default function CreatePyngForm({
rules={{
required: true,
validate: (value) => {
if (!value) {
return "Required";
}

const socialMediaBlocklist = [
"facebook.com",
"x.com",
Expand Down
7 changes: 6 additions & 1 deletion app/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export default function Header({ src, initialTheme }: HeaderProps) {
<div className="hidden lg:block">
<ThemeSelector initialTheme={initialTheme} />
</div>
<Auth />
<div className="hidden lg:block">
<Auth />
</div>
</div>
<div className="flex-none ml-2 lg:hidden">
<label
Expand Down Expand Up @@ -84,6 +86,9 @@ export default function Header({ src, initialTheme }: HeaderProps) {
<li className="lg:hidden mt-4">
<ThemeSelector initialTheme={initialTheme} />
</li>
<li className="lg:hidden mt-8 ml-4">
<Auth />
</li>
</ul>
</div>
</header>
Expand Down
13 changes: 11 additions & 2 deletions app/components/header/usage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ export default function Usage({
return null;
}

const [loading, setLoading] = useState(true);
const [totalUsage, setTotalUsage] = useState(0);

useEffect(() => {
const getUsage = async () => {
setLoading(true);
const totalUsage = await fetchUsage(
stripeCustomerId,
stripeSubscriptionId,
);
setTotalUsage(totalUsage);
setLoading(false);
};

getUsage();
Expand All @@ -38,10 +41,16 @@ export default function Usage({
return (
<button
type="button"
className="btn btn-ghost no-animation pointer-events-none select-text"
className="btn btn-ghost no-animation pointer-events-none"
>
Usage
<div className="badge">{totalUsage} runs</div>
<div className="badge badge-secondary">
{loading ? (
<span className="loading loading-dots loading-xs" />
) : (
`${totalUsage.toLocaleString()} runs`
)}
</div>
</button>
);
}
2 changes: 1 addition & 1 deletion app/components/popular-pyngs/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function PopularPyngsCard({
<div className="card-actions">
<button
type="button"
className="btn btn-outline w-full"
className="btn btn-neutral w-full"
onClick={handleClick}
>
Try Now
Expand Down
24 changes: 19 additions & 5 deletions app/pricing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,39 @@ export default async function PricingPage() {
<div className="collapse collapse-arrow bg-base-200 shadow-md">
<input type="radio" name="my-accordion-2" />
<div className="collapse-title text-xl font-medium">
Is there a free tier?
Can I have multiple Pyngs with different schedules?
</div>
<div className="collapse-content">
<p>Not at this time.</p>
<p>
Yes, each Pyng has its own schedule. For example, in the medium
usage estimate, we have 5 Pyngs that run every hour and 5 Pyngs
that run every 15 minutes.
</p>
</div>
</div>

<div className="collapse collapse-arrow bg-base-200 shadow-md">
<input type="radio" name="my-accordion-2" />
<div className="collapse-title text-xl font-medium">
What is the billing cycle?
Is there an always-free tier?
</div>
<div className="collapse-content">
<p>
Billing is done on a monthly basis. You will be billed at the
start of each month.
No. There are 100 free runs per month. After that, you will be
billed for each run.
</p>
</div>
</div>

<div className="collapse collapse-arrow bg-base-200 shadow-md">
<input type="radio" name="my-accordion-2" />
<div className="collapse-title text-xl font-medium">
What is the billing cycle?
</div>
<div className="collapse-content">
<p>Billing is done on a monthly basis.</p>
</div>
</div>
</div>
</div>
</PageContentContainer>
Expand Down
6 changes: 5 additions & 1 deletion app/trigger/first-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ export const firstRun = task({
},
});

await stripe.billing.meterEvents.create({
console.log("Creating billing meter event...");

const meterEvent = await stripe.billing.meterEvents.create({
event_name: "pyng_run",
payload: {
stripe_customer_id: output.stripeCustomerId,
},
});

console.log("Billing meter event created", meterEvent);
},
run: async (payload: {
pyngId: string;
Expand Down
31 changes: 17 additions & 14 deletions app/trigger/pyng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,29 @@ import { SYSTEM_PROMPT, USER_PROMPT } from "./prompts";
import scrape from "./scrape";
import stripe from "./stripe";

type PyngTaskOutput = {
stripeCustomerId: string;
};

export const pyngTask = schedules.task({
id: "pyng",
onSuccess: async (payload, output) => {
console.log("pyngTask onSuccess payload: ", payload);
console.log("pyngTask onSuccess output: ", output);
const { stripeCustomerId } = output as PyngTaskOutput;
await stripe.billing.meterEvents.create({
onSuccess: async (payload) => {
const pyngId = payload.externalId;
if (!pyngId) {
throw new Error("externalId (which is the pyngId) is required");
}

// current pyng
const currentPyng = await prisma.pyng.findUniqueOrThrow({
where: {
id: pyngId,
},
});

console.log("Creating billing meter event...");
const meterEvent = await stripe.billing.meterEvents.create({
event_name: "pyng_run",
payload: {
stripe_customer_id: stripeCustomerId,
stripe_customer_id: currentPyng.stripeCustomerId,
},
});
console.log("Billing meter event created", meterEvent);
},
run: async (payload) => {
const pyngId = payload.externalId;
Expand Down Expand Up @@ -119,9 +126,5 @@ export const pyngTask = schedules.task({
if (emailResponse.error) {
throw new Error(emailResponse.error.message);
}

return {
stripeCustomerId: currentPyng.stripeCustomerId,
} as PyngTaskOutput;
},
});

0 comments on commit 72681fe

Please sign in to comment.