Skip to content

Latest commit

 

History

History
252 lines (176 loc) · 9.36 KB

README.md

File metadata and controls

252 lines (176 loc) · 9.36 KB

Tip Land the SaaS platform for the tip of the day

Tip Land is a platform as a service for product creators and that can easily integrate the functionality of the tip of the day.

Many products today include daily tips for their best use in their interface, such as code editors, management systems among many others, Tip Land provides you with a platform with which you can create those tips for your products, through a API Key assigned to your account you can access the endpoint.

Made with Re2 Stack (Remix + Redis = Re2 Stack)

When two blazing-fast technologies come together to bring out the best of each other, something amazing happens:

In Remix the global state is the database and the database is the cache in Redis Stack.

Social Login Social Login

Dashboard Dashboard

Tips Tips

API Key Api Key

Stats Stats

Overview video

Embed your YouTube video

How it works

Stack Stack

How the data is stored:

Database Database

The project manages persistence through the Redis OM for Node.js, for the tips of the day we have the following properties

Tip

  • description: string
  • categoryId: string
  • userId: string
  • createAt: Date

To start data management with Redis, a function is performed that creates a client that receives the connection url from the environment variables.

import { Client } from "redis-om";

const redisClient = new Client();

async function redisConnect () {
    if (!redisClient.isOpen()) {
      await redisClient.open(process.env.REDIS_URL);
    }
};

export { redisClient, redisConnect };

Once having the connection, the Tip class is created, with its interface to define its attributes in Typescript and the schema

export interface Tip {
    description: string;
    categoryId: string;
    userId: string;
    createAt: Date;
    category?: Category
}

export class Tip extends Entity {}

const tipSchema = new Schema(Tip, {
    description: { type: "string" },
    categoryId: { type: "string", indexed: true },
    userId: { type: "string", indexed: true },
    createAt: { type: "date", sortable: true }
});

Through generating a repository is where the connection between the client and the schema is made

async function getTipRepository(): Promise<Repository<Tip>> {
    await redisConnect();
    const repository = redisClient.fetchRepository(tipSchema);
  
    await repository.createIndex();
    return repository;
}

The createTip function generates a tip entity based on the user's identifier

export async function createTip({ userId, description, categoryId } : TipCreate) : Promise<Tip> {
    const repository = await getTipRepository();
    return repository.createAndSave({ userId, description, categoryId, createAt: new Date() });
}

On the user interface side through the action function defined in Remix is where the form information is obtained and the createTip function is called

export async function action({ request }: ActionArgs) {
    const { userId } = await getAuth(request);

    if(!userId) {
        return redirect("/sign-up");
    }

    const formData = await request.formData();
    const intent = formData.get("intent") as IntentType; 
    
    if(intent === "create") {
        const description = formData.get("description") as string;
        const categoryId = formData.get("categoryId") as string;

        const tip = await createTip({ userId, categoryId, description });
        return json({ intent, tip });
    } 
    
}

How the data is accessed:

Through the getAllTipsByUserPaging function, the user identifier, the offset, and the elements that are consulted in total in the paging are received

export async function getAllTipsByUserPaging({ userId, offset = 0, perPage = 1}: TipSearch): Promise<Tip[]> {
    const repository = await getTipRepository();

    return repository.search()
            .where("userId")
            .equals(userId)
            .sortDescending("createAt")
            .return
            .page(offset, perPage);
}

On the user interface side, Remix determines that the loader function is in charge of calling the functions that access the data.

export async function loader({ request }: LoaderArgs) {
    const { userId } = await getAuth(request);
    
    if(!userId) {
        return redirect("/sign-up");
    }
    const offset = getQueryIntParameter(request, "offset", 0);
    const perPage = getQueryIntParameter(request, "per_page", 200); 

    const [total, plainTips, categories] = await Promise.all([ 
        countAllTipsByUser(userId), 
        getAllTipsByUserPaging({ userId, offset, perPage }), 
        getAllCategoriesByUser(userId) 
    ]);

    const tips = getTipsWithCategory({ tips: plainTips, categories });
    return json({ total, tips, categories, offset, perPage });
}

How to run it locally?

Prerequisites

  • Node >= v14.0.0
  • Redis Cloud account
  • Clerk dev account

Local installation

Create an .env file with the environment variables shown in the env.example file

REDIS_URL=

CLERK_FRONTEND_API=

CLERK_API_KEY=

CLERK_JWT_KEY=

Install dependencies

npm install

Run development mode

npm run dev

Deployment

To make deploys work, you need to create free account on Redis Cloud

Also the Clerk for handling authentication.

Vercel

Deploy with Vercel

More Information about Redis Stack

Here some resources to help you quickly get started using Redis Stack. If you still have questions, feel free to ask them in the Redis Discord or on Twitter.

Getting Started

  1. Sign up for a free Redis Cloud account using this link and use the Redis Stack database in the cloud.
  2. Based on the language/framework you want to use, you will find the following client libraries:

The above videos and guides should be enough to get you started in your desired language/framework. From there you can expand and develop your app. Use the resources below to help guide you further:

  1. Developer Hub - The main developer page for Redis, where you can find information on building using Redis with sample projects, guides, and tutorials.
  2. Redis Stack getting started page - Lists all the Redis Stack features. From there you can find relevant docs and tutorials for all the capabilities of Redis Stack.
  3. Redis Rediscover - Provides use-cases for Redis as well as real-world examples and educational material
  4. RedisInsight - Desktop GUI tool - Use this to connect to Redis to visually see the data. It also has a CLI inside it that lets you send Redis CLI commands. It also has a profiler so you can see commands that are run on your Redis instance in real-time
  5. Youtube Videos