WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Subscriber Check Feature - Frontend & Backend #670

@fullakingi

Description

@fullakingi

Hi @elitan - made progress on a feature for nhost that checks if an authorised user is on a table called subscribers.

  1. chose project at nhost back-end
  2. create a table called subscribed with the following fields:
  • id (UUID)
  • created_at (timestamp)
  • email (text)
  • subscribed(Boolean)
  1. to populate this table with subscribers we use mailchimp API.
    we set up a webhook " api-xxxxxx.nhost.app"

I am attaching the code for the back-end API:

it is in root/API/mailchimp

const http = require('https');

const graphQL = (query, variables) => {

  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-hasura-admin-secret': process.env.NHOST_HASURA_ADMIN_SECRET     
    },
  };

  return new Promise((resolve, reject) => {
    const request = http.request(
      process.env.NHOST_HASURA_URL,
      options,
      res => {
        if (res.statusCode !== 200) {
          res.resume();
          reject(res.statusMessage);
        }
        res.setEncoding('utf8');
        let rawData = '';
        res.on('data', chunk => {rawData += chunk})
        res.on('end', () => {
          if (!res.complete) {
            reject('Aborted');
          }
          resolve(JSON.parse(rawData));
        });
      }
    );
    request.on('error', reject);
    request.write(JSON.stringify({
      query,
      variables
    }));
    request.end();
  });
};

module.exports = (req, res) => {
  if (req.body && req.body.type && req.body.data && req.body.data.email) {
    graphQL(`mutation ($email: String, $subscribed: Boolean) {
      insert_subscribed_one(
        object: {
          email: $email,
          subscribed: $subscribed
        }, on_conflict: {
          constraint: subscribed_email_key,
          update_columns: [subscribed]
        }) {
        id
      }
    }`, {
      email: req.body.data.email,
      subscribed: req.body.type === 'subscribe'
    }).then((data) => {
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(JSON.stringify(data));
    }).catch(err => {
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(err.toString());
    })
  } else {
    res.writeHead(200,  { 'Content-Type': 'text/plain' });
    res.end('Bad request data');
  }
} 

in the frontend (next js), we change the private route:

/* eslint-disable react-hooks/rules-of-hooks */
import { useRouter } from 'next/router'
import { useAuth } from '@nhost/react-auth'
import Image from 'next/image'
import { useQuery, gql } from '@apollo/client'
import { nhost } from '../utils/nhost'

const IS_SUBSCRIBED = gql`
query ($email: String) {
  subscribed(where: {
    email: {_eq: $email}
    subscribed: {_eq: true}
  } ) {
    subscribed
  }
}
`;

function PrivateRouteInternal(props) {
  const router = useRouter()
  const { loading, data } = useQuery(
    IS_SUBSCRIBED,
    {
      variables: {
        email: nhost.auth.user().email
      }
    }
  );
  console.log(nhost.auth.user().email);
  if (loading) {
    return <div className="flex items-center justify-center">
      <p className="text-sm">2. Checking registration status...</p>
      <div>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    </div>
  }
  console.log(JSON.stringify(data));

  if (!(data && data.subscribed && data.subscribed[0])) {
    setTimeout(() => { router.push('/onboard') }, 3000);
    return <div className="flex items-center justify-center">
      <p className="text-sm justify-center">Email address does not seem to be registered. Please complete registration on the next screen.</p>
      <div>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    </div>
  }

  return props.children[0];
}


export function PrivateRoute(Component) {
  return (props) => {
    const router = useRouter()
    const { signedIn } = useAuth()
    // wait to see if the user is logged in or not.
    if (signedIn === null) {
      return <div className="flex items-center justify-center">
        <p className="text-sm">1: Checking authorisation...</p>
        <Image
          src="/loading.svg"
          alt="loading icon"
          width={100}
          height={100}
        />
      </div>
    }

    if (!signedIn) {
      router.push('/login')
      return <div>Redirecting...</div>
    }

    return <PrivateRouteInternal><Component {...props} /></PrivateRouteInternal>;
  }
}

We are still refining the front-end private route file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions