Skip to content

Commit

Permalink
Merge pull request #207 from RBND-studio/dev
Browse files Browse the repository at this point in the history
Merge dev
  • Loading branch information
VojtechVidra committed Mar 27, 2024
2 parents 340e5c0 + e198662 commit 37dc504
Show file tree
Hide file tree
Showing 30 changed files with 583 additions and 313 deletions.
12 changes: 6 additions & 6 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
"@radix-ui/react-slot": "^1.0.2",
"@rbnd/react-dark-mode": "^2.0.1",
"@supabase/ssr": "^0.1.0",
"@supabase/supabase-js": "^2.39.7",
"@visx/axis": "^3.9.0",
"@supabase/supabase-js": "^2.40.0",
"@visx/axis": "^3.10.1",
"@visx/event": "^3.3.0",
"@visx/group": "^3.3.0",
"@visx/responsive": "^3.3.0",
"@visx/responsive": "^3.10.2",
"@visx/scale": "^3.5.0",
"@visx/shape": "^3.5.0",
"@visx/tooltip": "^3.3.0",
"dayjs": "^1.11.10",
"icons": "workspace:*",
"monaco-editor": "^0.44.0",
"next": "14.1.3",
"next": "14.1.4",
"posthog-js": "^1.108.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -43,11 +43,11 @@
"ui": "workspace:*"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.3",
"@next/eslint-plugin-next": "14.1.4",
"@pandacss/dev": "0.34.3",
"@types/node": "^20.11.29",
"@types/react": "^18.2.67",
"@types/react-dom": "^18.2.19",
"@types/react-dom": "^18.2.22",
"eslint-config-custom": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "5.4.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = {
export const CreateFlow: FC<Props> = ({ projectId, organizationId }) => {
return (
<Flex gap="space12">
<NumberCircle>3</NumberCircle>
<NumberCircle>4</NumberCircle>
<Flex
alignItems="center"
flex="1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ const CDNSnippet: FC<Props> = async ({ projectId }) => {
<CodeHighlight className={css({ margin: "0!", width: "100%" })}>
<pre>
<code className="index.html">{`<script>
flows.init({
projectId: "${projectId}",
// Optionally define local flows.
flows: [],
});
flows.init({ projectId: "${projectId}" });
</script>`}</code>
</pre>
</CodeHighlight>
Expand All @@ -61,17 +57,47 @@ const NPMSnippet: FC<Props> = ({ projectId }) => {
<pre>
<code className="flows.js">{`import { init } from "@flows/js";
init({
projectId: "${projectId}",
// Optionally define local flows.
flows: [],
});`}</code>
init({ projectId: "${projectId}" });`}</code>
</pre>
</CodeHighlight>
</Flex>
);
};

const ReactSnippet: FC<Props> = ({ projectId }) => {
return (
<Flex flexDirection="column" gap="space16">
<Text>First Install the Flows SDK library via a NPM package manager.</Text>
<CodeHighlight className={css({ margin: "0!" })} lineNumbers={false}>
<pre>
<code className="sh">npm i @flows/js</code>
</pre>
</CodeHighlight>
<Text>Create Flows component and initialize it with your project ID.</Text>
<CodeHighlight className={css({ margin: "0!" })}>
<pre>
<code className="flows.tsx">{`"use client";
import { init } from "@flows/js";
import { useEffect } from "react";
export const Flows = () => {
useEffect(() => {
init({ projectId: "${projectId}" });
}, []);
return null;
}`}</code>
</pre>
</CodeHighlight>
<Text>
Don&apos;t forget to render the component in your layout.tsx (in case of NextJS) or App.tsx
(for most of the other frameworks).
</Text>
</Flex>
);
};

export const InstallInstructions: FC<Props> = ({ projectId }) => {
return (
<Flex gap="space12">
Expand All @@ -89,12 +115,16 @@ export const InstallInstructions: FC<Props> = ({ projectId }) => {
overflow: "hidden",
width: "100%",
})}
defaultValue="cdn"
defaultValue="react"
>
<TabsList>
<TabsTrigger value="cdn">CDN</TabsTrigger>
<TabsTrigger value="npm">NPM</TabsTrigger>
<TabsTrigger value="react">React</TabsTrigger>
<TabsTrigger value="cdn">JS Snippet (CDN)</TabsTrigger>
<TabsTrigger value="npm">NPM package</TabsTrigger>
</TabsList>
<TabsContent value="react">
<ReactSnippet projectId={projectId} />
</TabsContent>
<TabsContent value="cdn">
<CDNSnippet projectId={projectId} />
</TabsContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ import { CreateFlow } from "./create-flow";
import { Domains } from "./domains";
import { InstallInstructions } from "./install-instructions";
import { LearnMore } from "./learn-more";
import { Verify } from "./verify";

type Props = {
params: { projectId: string; organizationId: string };
};

export default function ProjectSettingsPage({ params }: Props): JSX.Element {
return (
<Flex flexDirection="column" gap="space40" mt="space24">
<Flex flexDirection="column" gap="space48" mt="space24">
<Flex flexDirection="column" gap="space8">
<Text variant="titleXl">Welcome to Flows 👋</Text>
<Text color="muted">
Here&apos;s how to get up and running with Flows in three easy steps.
</Text>
<Text color="muted">Here’s how to get up and running with Flows in four easy steps.</Text>
</Flex>
<InstallInstructions organizationId={params.organizationId} projectId={params.projectId} />
<Domains organizationId={params.organizationId} projectId={params.projectId} />
<Verify />
<CreateFlow organizationId={params.organizationId} projectId={params.projectId} />
<LearnMore />
</Flex>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Flex } from "@flows/styled-system/jsx";
import Link from "next/link";
import type { FC } from "react";
import { links } from "shared";
import { Button, Text } from "ui";

import { NumberCircle } from "./number-circle";

export const Verify: FC = () => {
return (
<Flex gap="space12">
<NumberCircle>3</NumberCircle>
<Flex
alignItems="center"
flex="1"
gap="space16"
justifyContent="space-between"
mdDown={{ flexDirection: "column", justifyContent: "unset", alignItems: "flex-start" }}
>
<Flex flexDirection="column" gap="space4">
<Text variant="titleL">Verify the installation</Text>
<Text color="muted">
Verify that the Flows SDK is installed correctly on your website before you start
creating flows.
</Text>
</Flex>
<Button asChild size="medium" variant="primary">
<Link target="_blank" href={links.docsVerifyInstallation}>
Learn how
</Link>
</Button>
</Flex>
</Flex>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -59,35 +59,46 @@ export const ProjectDomains: FC<Props> = ({ project }) => {
<Text variant="titleL">{t.project.domains.domains}</Text>
<Text color="muted">{t.project.domains.description}</Text>
</Flex>
{fields.length > 0 && (
<Flex direction="column" gap="space8">
{fields.map((field, i) => {
return (
<Flex direction="column" gap="space4" key={field.id}>
<Flex gap="space8">
<Input
{...register(`domains.${i}.value`, {
validate: (v) => {
if (!isValidUrl(v)) return t.project.domains.invalidDomain;
},
})}
className={css({ flex: 1 })}
defaultValue={formState.defaultValues?.domains?.[i]?.value}
placeholder="https://example.com"
required
/>
<Button onClick={() => remove(i)} variant="secondary">
{t.actions.remove}
</Button>
</Flex>
<Description color="danger">
{formState.errors.domains?.[i]?.value?.message}
</Description>
</Flex>
);
})}

<Flex direction="column" gap="space8">
<Flex gap="space8">
<Input
className={css({ flex: 1 })}
description="Localhost is allowed by default"
disabled
value="http://localhost"
/>
<Button disabled variant="secondary">
{t.actions.remove}
</Button>
</Flex>
)}
{fields.map((field, i) => {
return (
<Flex direction="column" gap="space4" key={field.id}>
<Flex gap="space8">
<Input
{...register(`domains.${i}.value`, {
validate: (v) => {
if (!isValidUrl(v)) return t.project.domains.invalidDomain;
},
})}
className={css({ flex: 1 })}
defaultValue={formState.defaultValues?.domains?.[i]?.value}
placeholder="https://example.com"
required
/>
<Button onClick={() => remove(i)} variant="secondary">
{t.actions.remove}
</Button>
</Flex>
<Description color="danger">
{formState.errors.domains?.[i]?.value?.message}
</Description>
</Flex>
);
})}
</Flex>

<div>
<Button
onClick={() => append({ value: "" })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const StepPreview: FC<Props> = ({ selectedStep }) => {
overflow="hidden"
transform="translate3d(0,0,0)"
{...{
"& .flows-root": { pointerEvents: "none!" },
"& .flows-root *": { pointerEvents: "none!" },
}}
>
<div
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/auth/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const AuthProvider: FC<Props> = ({ children }) => {

useEffect(() => {
if (!auth) return;
posthog.identify(auth.user.email);
posthog.identify(auth.user.email, { email: auth.user.email });
}, [auth]);

const value = useMemo(
Expand Down
4 changes: 2 additions & 2 deletions apps/app/src/components/providers/posthog-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"use client";

import { POSTHOG_KEY } from "lib/constants";
import { POSTHOG_KEY, PRODUCTION } from "lib/constants";
import { posthog } from "posthog-js";
import { PostHogProvider } from "posthog-js/react";
import type { FC, ReactNode } from "react";

if (typeof window !== "undefined") {
if (typeof window !== "undefined" && PRODUCTION) {
posthog.init(POSTHOG_KEY, {
api_host: "https://app.posthog.com",
});
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/flows/flows.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export class FlowsService {
});
if (!flow) throw new NotFoundException();

if (!flow.draft_version_id) throw new BadRequestException("No draft version found");
if (!flow.draft_version_id) return;

const updateVersionQuery = this.databaseService.db
.update(flowVersions)
Expand Down
6 changes: 3 additions & 3 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"dependencies": {
"@flows/js": "0.0.47",
"next": "14.1.3",
"next": "14.1.4",
"next-sitemap": "^4.2.3",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.4",
Expand All @@ -25,11 +25,11 @@
"shared": "workspace:*"
},
"devDependencies": {
"@next/eslint-plugin-next": "14.1.3",
"@next/eslint-plugin-next": "14.1.4",
"@pandacss/dev": "0.34.3",
"@types/node": "^20.11.29",
"@types/react": "^18.2.67",
"@types/react-dom": "^18.2.19",
"@types/react-dom": "^18.2.22",
"eslint-config-custom": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "5.4.2"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/docs/public/getting-started/modal-step.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions apps/docs/src/pages/getting-started/_meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"install-flows": "Install Flows",
"identify-users": "Identify users",
"concepts": "Concepts"
}
38 changes: 38 additions & 0 deletions apps/docs/src/pages/getting-started/identify-users.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Identify users
description: Learn how to identify users in your application.
---

# Identify users

For flows to show up only once to a user, you need to identify the user. This is done by passing a `userId` parameter to the `init` function. This will allow you to count unique users that have seen your flows and show the flows only once to a specific user.

```js
init({
// Unique identifier for the user
// Prefer database ID over email if you're concerned about privacy of your users
userId: "xxxx"

projectId: "...",
})
```

The `userId` parameter can be any unique identifier for the user. We recommend using a database ID or a UUID. We hash the user ID on the client side before sending it to our servers to protect your users' privacy.

## Adding user properties

To target your flows to specific users, you can optionally pass user properties to the `init` function. These properties can be used to target flows to specific users based on their properties.

```js
init({
userId: "xxxx",
projectId: "...",
userProperties: {
email: "john.doe@flows.sh"
name: "John Doe",
plan: "premium"
},
})
```

To protect your users' privacy Flows don’t store any personal data about your users. When you setup targeting based on user properties the evaluation is done on the client side. This means that the user data is never sent to our servers.
Loading

0 comments on commit 37dc504

Please sign in to comment.