Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default async function ApplicationPage({
include: ["rewards", "defaultDiscount"],
});

if (!program || !program.defaultRewardId) {
if (!program) {
notFound();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { getProgram } from "@/lib/fetchers/get-program";
import { getReward } from "@/lib/fetchers/get-reward";
import { formatRewardDescription } from "@/ui/partners/format-reward-description";
import { prisma } from "@dub/prisma";
import { Prisma } from "@dub/prisma/client";
import { Wordmark } from "@dub/ui";
import { APP_DOMAIN } from "@dub/utils";
import { constructMetadata } from "@dub/utils/src/functions";
Expand Down Expand Up @@ -34,11 +33,6 @@ export async function generateMetadata({

export async function generateStaticParams() {
const programs = await prisma.program.findMany({
where: {
landerData: {
not: Prisma.JsonNull,
},
},
select: {
slug: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function ApplyPage({
include: ["rewards", "defaultDiscount"],
});

if (!program || !program.landerData || !program.defaultRewardId) {
if (!program || !program.landerData || !program.landerPublishedAt) {
notFound();
}

Expand Down
3 changes: 3 additions & 0 deletions apps/web/app/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
landerData: {
not: Prisma.JsonNull,
},
landerPublishedAt: {
not: null,
},
},
});

Expand Down
1 change: 1 addition & 0 deletions apps/web/lib/actions/partners/update-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const updateProgramAction = authActionClient
wordmark: wordmarkUrl ?? undefined,
brandColor,
landerData: landerData === null ? Prisma.JsonNull : landerData,
landerPublishedAt: landerData ? new Date() : undefined,
domain,
url,
linkStructure,
Expand Down
1 change: 1 addition & 0 deletions apps/web/lib/zod/schemas/programs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const ProgramSchema = z.object({

export const ProgramWithLanderDataSchema = ProgramSchema.extend({
landerData: programLanderSchema.nullish(),
landerPublishedAt: z.date().nullish(),
});

export const updateProgramSchema = z.object({
Expand Down
110 changes: 110 additions & 0 deletions apps/web/scripts/framer/process-lead-events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// @ts-nocheck

import { prisma } from "@dub/prisma";
import { chunk } from "@dub/utils";
import "dotenv-flow/config";
import * as fs from "fs";
import * as Papa from "papaparse";

type RawDataProps = {
event_name: string;
timestamp: string;
customer_id: string;
link_id: string;
};

type ProcessedDataProps = {
via: string;
externalId: string;
eventName: string;
creationDate: Date;
};

let rawData: RawDataProps[] = [];
let customerIdsSet = new Set<string>();
let linkIdsSet = new Set<string>();

const BATCH = 7;
const FRAMER_WORKSPACE_ID = "xxx";

async function main() {
Papa.parse(
fs.createReadStream(`get_framer_lead_events_${BATCH}.csv`, "utf-8"),
{
header: true,
skipEmptyLines: true,
step: (result: { data: RawDataProps }) => {
const { customer_id, link_id } = result.data;
rawData.push(result.data);
linkIdsSet.add(link_id);
customerIdsSet.add(customer_id);
},
complete: async () => {
const linkIdsArray = Array.from(linkIdsSet);
const customerIdsArray = Array.from(customerIdsSet);

console.log(
`Found ${linkIdsArray.length} links and ${customerIdsArray.length} customers`,
);

const links = await prisma.link.findMany({
where: {
id: {
in: linkIdsArray,
},
projectId: FRAMER_WORKSPACE_ID,
},
select: {
id: true,
key: true,
},
});

let customers: { id: string; externalId: string | null }[] = [];
const customerIdChunks = chunk(customerIdsArray, 1000);
for (const customerIdChunk of customerIdChunks) {
const data = await prisma.customer.findMany({
where: {
id: {
in: customerIdChunk,
},
projectId: FRAMER_WORKSPACE_ID,
},
select: {
id: true,
externalId: true,
},
});
customers.push(...data);
}

console.log(`Found ${customers.length} customers`);

const processedData = rawData
.map((data) => {
const link = links.find((link) => link.id === data.link_id);
const customer = customers.find(
(customer) => customer.id === data.customer_id,
);
if (!link || !customer || !customer.externalId) {
return null;
}
return {
via: link.key,
externalId: customer.externalId,
eventName: data.event_name,
creationDate: new Date(data.timestamp),
};
})
.filter((data) => data !== null) satisfies ProcessedDataProps[];

fs.writeFileSync(
`processed_framer_lead_events_${BATCH}.csv`,
Papa.unparse(processedData),
);
},
},
);
}

main();
45 changes: 45 additions & 0 deletions apps/web/scripts/tinybird/delete-links.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import "dotenv-flow/config";

// update tinybird sale event
async function main() {
const deleteCondition = "domain = 'xyz'";

// delete data from tinybird
const deleteRes = await Promise.allSettled([
deleteData({
dataSource: "dub_links_metadata",
deleteCondition,
}),
deleteData({
dataSource: "dub_links_metadata_latest",
deleteCondition,
}),
deleteData({
dataSource: "dub_regular_links_metadata_latest",
deleteCondition,
}),
]);
console.log(deleteRes);
}

const deleteData = async ({
dataSource,
deleteCondition,
}: {
dataSource: string;
deleteCondition: string;
}) => {
return fetch(
`https://api.us-east.tinybird.co/v0/datasources/${dataSource}/delete`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TINYBIRD_API_KEY}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: `delete_condition=${deleteCondition}`,
},
).then((res) => res.json());
};

main();
35 changes: 23 additions & 12 deletions apps/web/ui/partners/design/branding-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ export function useBrandingFormContext() {

export function BrandingForm() {
const { defaultProgramId } = useWorkspace();
const { program, mutate, loading } = useProgram<ProgramWithLanderDataProps>(
const {
program,
mutate: mutateProgram,
loading,
} = useProgram<ProgramWithLanderDataProps>(
{
query: { includeLanderData: true },
},
Expand All @@ -63,7 +67,7 @@ export function BrandingForm() {
return (
<BrandingFormInner
program={program}
mutate={mutate}
mutateProgram={mutateProgram}
draft={draft}
setDraft={setDraft}
/>
Expand All @@ -90,12 +94,12 @@ const PREVIEW_TABS = [

function BrandingFormInner({
program,
mutate,
mutateProgram,
draft,
setDraft,
}: {
program: ProgramWithLanderDataProps;
mutate: KeyedMutator<ProgramWithLanderDataProps>;
mutateProgram: KeyedMutator<ProgramWithLanderDataProps>;
draft: BrandingFormData | null;
setDraft: (draft: BrandingFormData | null) => void;
}) {
Expand All @@ -120,13 +124,17 @@ function BrandingFormInner({
handleSubmit,
reset,
setError,
formState: { isDirty, isSubmitting },
formState: { isDirty, isSubmitting, isSubmitSuccessful },
getValues,
} = form;

const { executeAsync } = useAction(updateProgramAction, {
const { executeAsync, isPending } = useAction(updateProgramAction, {
async onSuccess() {
await mutateProgram();
toast.success("Program updated successfully.");
mutate();
// Reset form state to clear isSubmitSuccessful
const currentValues = getValues();
reset(currentValues);
},
onError({ error }) {
console.error(error);
Expand All @@ -146,16 +154,19 @@ function BrandingFormInner({

const [isTabPopoverOpen, setIsTabPopoverOpen] = useState(false);

// Disable publish button when:
// - there are no changes
// - the program lander is already published
const disablePublishButton =
!isDirty && program.landerPublishedAt ? true : false;

return (
<form
onSubmit={handleSubmit(async (data) => {
await executeAsync({
workspaceId: workspaceId!,
...data,
});

// Reset isDirty state
reset(data);
})}
className="overflow-hidden rounded-lg border border-neutral-200 bg-neutral-100"
>
Expand Down Expand Up @@ -227,8 +238,8 @@ function BrandingFormInner({
type="submit"
variant="primary"
text="Publish"
loading={isSubmitting}
disabled={!isDirty}
loading={isPending || isSubmitting || isSubmitSuccessful}
disabled={disablePublishButton}
className="h-8 w-fit px-3"
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/prisma/schema/program.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ model Program {
defaultDiscountId String? @unique // default discount for the program
embedData Json? @db.Json
landerData Json? @db.Json
landerPublishedAt DateTime?
resources Json? @db.Json
termsUrl String? @db.Text
helpUrl String? @db.Text
Expand Down