Skip to content

Commit

Permalink
fix: simplify signin
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSnow committed Feb 29, 2024
1 parent a4ba637 commit e83d71a
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 146 deletions.
18 changes: 5 additions & 13 deletions src/components/EmailForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import { Field as FormField, useForm } from 'vee-validate'
import { useAutoAnimate } from '@formkit/auto-animate/vue'
import * as z from 'zod'
import { useModel } from 'vue'
import type { Mode } from '~/composables/paywall-mode'
const props = defineProps<{
mode: Mode
email: string
buttonText: string
}>()
defineEmits<{
Expand All @@ -34,15 +31,14 @@ const form = useForm({
})
const emailInput = useModel(props, 'email')
const { subscribe } = useSubscribe(toRef(props, 'mode'))
const showLoginDialog = ref(false)
const { subscribe } = useSubscribe()
const onSubmit = form.handleSubmit(async (values) => {
const res = await subscribe(values)
if (res.ok && !res.token) {
showLoginDialog.value = true
if (res.ok && res.token) {
$paywall.setKey('token', res.token)
}
// TODO: error handling
})
const [formItem, setAnimate] = useAutoAnimate({ duration: 200 })
Expand Down Expand Up @@ -75,10 +71,6 @@ onMounted(async () => {
</FormItem>
</FormField>

<Button type="submit" tabindex="-1" class="w-full bg-sp_primary text-white">
{{ buttonText }}
</Button>

<LoginDialog v-model:open="showLoginDialog" />
<Button type="submit" tabindex="-1" class="w-full bg-sp_primary text-white">Submit</Button>
</form>
</template>
24 changes: 1 addition & 23 deletions src/components/LeakyPaywall.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ initConfig()
const config = useStore($config)
const paywall = useStore($paywall)
const { mode, primaryButton, reset, secondaryButton, toggleMode } = usePaywallMode()
const themeConfig = computed(() => ({
'--sp-primary': config.value.primaryColor,
}))
Expand Down Expand Up @@ -95,11 +93,6 @@ onMounted(async () => {
const emailInput = ref('')
function switchMode() {
// After this step, the form will be reset
toggleMode()
}
// Unlock scroll if user scroll up
useEventListener(window, 'wheel', (event) => {
if (event.deltaY <= -5) {
Expand Down Expand Up @@ -155,15 +148,6 @@ whenever(
},
{ immediate: true },
)
// reset form content after close
whenever(
logicNot(show),
() => {
reset()
},
{ flush: 'post' },
)
</script>

<template>
Expand Down Expand Up @@ -193,13 +177,7 @@ whenever(
</p>

<!-- email form -->
<EmailForm :key="mode" v-model:email="emailInput" :mode="mode" :button-text="primaryButton" />

<Separator class="my-2" />

<Button class="text-gray-600" tabindex="-1" variant="ghost" @click="switchMode">
{{ secondaryButton }}
</Button>
<EmailForm v-model:email="emailInput" />
</div>
</CardContent>
</Card>
Expand Down
26 changes: 0 additions & 26 deletions src/composables/paywall-mode.ts

This file was deleted.

78 changes: 16 additions & 62 deletions src/composables/subscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ interface SubscribeInput {

interface SuccessSubscribeReturn {
ok: true
// Sign in require to check the email
token?: string
}

Expand All @@ -28,88 +27,43 @@ interface FailSubscribeReturn {

type SubscribeReturn = SuccessSubscribeReturn | FailSubscribeReturn

export function useSubscribe(mode: Ref<'subscribe' | 'login'>) {
const { executeMutation: requestSignInSubscriberMutate } = useMutation(
export function useSubscribe() {
const { executeMutation: signInPaywall } = useMutation(
graphql(`
mutation RequestSignInSubscriber($email: EmailString!, $referer: String!, $from: String!) {
requestSignInSubscriber(input: { email: $email, referer: $referer, from: $from })
mutation SignInPaywall($email: EmailString!) {
signInLeakySubscriber(input: { email: $email })
}
`),
)

const { executeMutation: signUpSubscriberMutate } = useMutation(
graphql(`
mutation SignUpSubscriber($email: EmailString!, $referer: String!, $from: String!) {
signUpSubscriber(input: { email: $email, referer: $referer, from: $from })
}
`),
)

function collectReferer() {
return {
referer: document.referrer || location.origin,
from: location.href,
}
}

async function doLogin(input: SubscribeInput): Promise<SubscribeReturn> {
const res = await requestSignInSubscriberMutate({
email: input.email,
...collectReferer(),
})

if (res.error) {
return {
ok: false,
isBadRequest: isBadRequest(res.error.graphQLErrors?.[0]),
error: res.error,
}
}

return {
ok: true,
}
}

async function doSignup(input: SubscribeInput): Promise<SubscribeReturn> {
const res = await signUpSubscriberMutate({
const res = await signInPaywall({
email: input.email,
...collectReferer(),
})

if (res.error) {
if (res.error || !res.data?.signInLeakySubscriber) {
return {
ok: false,
isBadRequest: isBadRequest(res.error.graphQLErrors?.[0]),
error: res.error,
isBadRequest: isBadRequest(res.error?.graphQLErrors?.[0]),
error: res.error ?? createUnknownError(),
}
}

return {
ok: true,
token: res.data?.signUpSubscriber,
token: res.data.signInLeakySubscriber,
}
}

return {
async subscribe(input: SubscribeInput): Promise<SubscribeReturn> {
const actions = mode.value === 'login' ? [doLogin, doSignup] : [doSignup, doLogin]
for (const action of actions) {
const result = await action(input)
if (!result.ok && !result.isBadRequest) {
return result
}
if (result.ok) {
return result
}
}
return {
ok: false,
isBadRequest: false,
error: new CombinedError({
networkError: new Error('Unknown error'),
}),
}
return doLogin(input)
},
}
}

function createUnknownError() {
return new CombinedError({
networkError: new Error('Unknown error'),
})
}
9 changes: 2 additions & 7 deletions src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
const documents = {
"\n mutation VerifySubscriberEmail($token: String!) {\n verifySubscriberEmail(token: $token)\n }\n ": types.VerifySubscriberEmailDocument,
"\n mutation SignInSubscriber($token: String!) {\n signInSubscriber(token: $token)\n }\n ": types.SignInSubscriberDocument,
"\n mutation RequestSignInSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n requestSignInSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n ": types.RequestSignInSubscriberDocument,
"\n mutation SignUpSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n signUpSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n ": types.SignUpSubscriberDocument,
"\n mutation SignInPaywall($email: EmailString!) {\n signInLeakySubscriber(input: { email: $email })\n }\n ": types.SignInPaywallDocument,
"\n mutation TrackSubscriberActivity($input: TrackSubscriberActivityInput!) {\n trackSubscriberActivity(input: $input)\n }\n ": types.TrackSubscriberActivityDocument,
};

Expand Down Expand Up @@ -45,11 +44,7 @@ export function graphql(source: "\n mutation SignInSubscriber($token: Strin
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation RequestSignInSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n requestSignInSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n "): (typeof documents)["\n mutation RequestSignInSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n requestSignInSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n "];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n mutation SignUpSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n signUpSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n "): (typeof documents)["\n mutation SignUpSubscriber($email: EmailString!, $referer: String!, $from: String!) {\n signUpSubscriber(input: { email: $email, referer: $referer, from: $from })\n }\n "];
export function graphql(source: "\n mutation SignInPaywall($email: EmailString!) {\n signInLeakySubscriber(input: { email: $email })\n }\n "): (typeof documents)["\n mutation SignInPaywall($email: EmailString!) {\n signInLeakySubscriber(input: { email: $email })\n }\n "];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
58 changes: 43 additions & 15 deletions src/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,12 @@ export type FacebookSearchPage = {
name: Scalars['String']['output'];
};

export type HubSpotInfo = {
__typename?: 'HubSpotInfo';
/** whether the integration is activated or not */
activated_at?: Maybe<Scalars['DateTime']['output']>;
};

export type IframelyIframelyInput = {
/**
* iframely params,
Expand Down Expand Up @@ -1627,6 +1633,8 @@ export type Mutation = {
confirmCustomDomain: Scalars['Boolean']['output'];
/** confirm account email */
confirmEmail: Scalars['Boolean']['output'];
/** initiate OAuth for HubSpot and return the redirect URL */
connectHubSpot: Scalars['String']['output'];
/** initiate OAuth for Webflow and return the redirect URL */
connectWebflow: Scalars['String']['output'];
createAppSubscription: Scalars['Boolean']['output'];
Expand Down Expand Up @@ -1733,6 +1741,8 @@ export type Mutation = {
* @deprecated No longer supported
*/
disableSubscription: Site;
/** disconnect HubSpot integration */
disconnectHubSpot: Scalars['Boolean']['output'];
/** disconnect specific integration */
disconnectIntegration: Integration;
/** disconnect stripe connect */
Expand Down Expand Up @@ -1864,6 +1874,8 @@ export type Mutation = {
signIframelySignature: Scalars['String']['output'];
/** sign in to the app */
signIn: AuthToken;
/** sign up/in to customer site */
signInLeakySubscriber: Scalars['String']['output'];
/** sign in to customer site */
signInSubscriber: Scalars['String']['output'];
/** sign out of the app */
Expand Down Expand Up @@ -2539,6 +2551,11 @@ export type MutationSignInArgs = {
};


export type MutationSignInLeakySubscriberArgs = {
input: SignInLeakySubscriberInput;
};


export type MutationSignInSubscriberArgs = {
token: Scalars['String']['input'];
};
Expand Down Expand Up @@ -2843,6 +2860,18 @@ export type MutationVerifySubscriberEmailArgs = {
token: Scalars['String']['input'];
};

export type Notification = {
__typename?: 'Notification';
/** notification meta data */
data?: Maybe<Scalars['JSON']['output']>;
/** notification id */
id: Scalars['ID']['output'];
/** notification create time */
occurred_at: Scalars['DateTime']['output'];
/** notification state */
type: Scalars['String']['output'];
};

export type OptInWordPressFeatureInput = {
/** feature Type */
key: WordPressOptionalFeatureType;
Expand Down Expand Up @@ -3039,6 +3068,10 @@ export type Query = {
/** get specific email */
email?: Maybe<Email>;
facebookPages: Array<FacebookSearchPage>;
/** whether the HubSpot OAuth has been completed or not */
hubSpotAuthorized: Scalars['Boolean']['output'];
/** get HubSpot information */
hubSpotInfo: HubSpotInfo;
/**
* make a iframely request for specific url
* @deprecated use signIframelySignature mutation
Expand All @@ -3061,6 +3094,8 @@ export type Query = {
me: User;
/** media info */
media: Media;
/** fetch notifications */
notifications: Array<Notification>;
/** get specific page */
page?: Maybe<Page>;
/** fetch pages */
Expand Down Expand Up @@ -3760,6 +3795,11 @@ export type ShopifyProductVariant = {
title: Scalars['String']['output'];
};

export type SignInLeakySubscriberInput = {
/** subscriber email */
email: Scalars['EmailString']['input'];
};

export type SignUpInput = {
appsumo_code?: InputMaybe<Scalars['String']['input']>;
campaign?: InputMaybe<Scalars['JSON']['input']>;
Expand Down Expand Up @@ -5233,23 +5273,12 @@ export type SignInSubscriberMutationVariables = Exact<{

export type SignInSubscriberMutation = { __typename?: 'Mutation', signInSubscriber: string };

export type RequestSignInSubscriberMutationVariables = Exact<{
export type SignInPaywallMutationVariables = Exact<{
email: Scalars['EmailString']['input'];
referer: Scalars['String']['input'];
from: Scalars['String']['input'];
}>;


export type RequestSignInSubscriberMutation = { __typename?: 'Mutation', requestSignInSubscriber: boolean };

export type SignUpSubscriberMutationVariables = Exact<{
email: Scalars['EmailString']['input'];
referer: Scalars['String']['input'];
from: Scalars['String']['input'];
}>;


export type SignUpSubscriberMutation = { __typename?: 'Mutation', signUpSubscriber: string };
export type SignInPaywallMutation = { __typename?: 'Mutation', signInLeakySubscriber: string };

export type TrackSubscriberActivityMutationVariables = Exact<{
input: TrackSubscriberActivityInput;
Expand All @@ -5261,6 +5290,5 @@ export type TrackSubscriberActivityMutation = { __typename?: 'Mutation', trackSu

export const VerifySubscriberEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifySubscriberEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifySubscriberEmail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode<VerifySubscriberEmailMutation, VerifySubscriberEmailMutationVariables>;
export const SignInSubscriberDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SignInSubscriber"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"token"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"signInSubscriber"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"token"},"value":{"kind":"Variable","name":{"kind":"Name","value":"token"}}}]}]}}]} as unknown as DocumentNode<SignInSubscriberMutation, SignInSubscriberMutationVariables>;
export const RequestSignInSubscriberDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RequestSignInSubscriber"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"EmailString"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"referer"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"from"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"requestSignInSubscriber"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"referer"},"value":{"kind":"Variable","name":{"kind":"Name","value":"referer"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"from"},"value":{"kind":"Variable","name":{"kind":"Name","value":"from"}}}]}}]}]}}]} as unknown as DocumentNode<RequestSignInSubscriberMutation, RequestSignInSubscriberMutationVariables>;
export const SignUpSubscriberDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SignUpSubscriber"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"EmailString"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"referer"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"from"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"signUpSubscriber"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"referer"},"value":{"kind":"Variable","name":{"kind":"Name","value":"referer"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"from"},"value":{"kind":"Variable","name":{"kind":"Name","value":"from"}}}]}}]}]}}]} as unknown as DocumentNode<SignUpSubscriberMutation, SignUpSubscriberMutationVariables>;
export const SignInPaywallDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SignInPaywall"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"EmailString"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"signInLeakySubscriber"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}}]}]}}]} as unknown as DocumentNode<SignInPaywallMutation, SignInPaywallMutationVariables>;
export const TrackSubscriberActivityDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"TrackSubscriberActivity"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"TrackSubscriberActivityInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"trackSubscriberActivity"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<TrackSubscriberActivityMutation, TrackSubscriberActivityMutationVariables>;

0 comments on commit e83d71a

Please sign in to comment.