Skip to content

Instantly share code, notes, and snippets.

View sergiodxa's full-sized avatar

Sergio Xalambrí sergiodxa

View GitHub Profile
@sergiodxa
sergiodxa / remix-auth.ts
Created July 21, 2021 23:25
Remix authentication library usage example
// create a session storage instance
let sessionStorage = createCookieSessionStorage();
// create authenticator instance
let authenticator = new Authenticator<User>(
sessionStorage
);
// configure the authenticator to use the Auth0 strategy for sign-in
authenticator.use(
@sergiodxa
sergiodxa / csrf.tsx
Last active September 9, 2022 18:03
A module with the implementation for CSRF protection in Remix
import { randomBytes } from 'crypto';
import * as React from 'react';
import { Request, Session } from 'remix';
import { parseBody, parseParams } from './parse-body';
/**
* An error that is thrown when a CSRF token is missing or invalid.
* @example
* throw new InvalidAuthenticityToken("Can't verify CSRF token authenticity.");
* @example
@sergiodxa
sergiodxa / serializer.ts
Last active May 26, 2021 01:50
Serializer in TS similar to ActiveModel::Serializer
abstract class Serializer {
abstract attributes: string[];
[customAttribute: string]: unknown; // this allow this[attribute] to work so we can use getters to add extra attributes
constructor(protected input: Record<string, unknown>) {}
private filterAttributes() {
return Object.fromEntries(
this.attributes.map((attribute) => {
@sergiodxa
sergiodxa / use-translations.tsx
Last active May 11, 2021 00:11
A custom Hook built on top of React Query to use translations from a backend
import ms from "ms";
import * as React from "react";
import { useQuery } from "react-query";
import { hasOwn } from "../utils";
let isProduction = process.env.NODE_ENV === "production";
export interface Translations {
[key: string]: string;
}
@sergiodxa
sergiodxa / react-query-crud.ts
Created February 10, 2021 00:28
CRUD mutations (not read) for React Query + TS
import { useMutation, UseMutationOptions } from "react-query";
import { pluralize, singularize } from "inflected";
import { generatePath } from "react-router-dom";
type Config<Input, Output, Error> = {
/**
* Any React Query option for useMutation
* @type {UseMutationOptions<Output, APIError<Error>, Input>}
*/
options?: UseMutationOptions<Output, APIError<Error>, Input>;
@sergiodxa
sergiodxa / form.tsx
Created January 10, 2021 01:21
A Form component which automatically run a React Query v2 mutation
import { useCallback, ReactNode, FormEventHandler } from "react";
import { MutationResultPair, MutateConfig, QueryStatus } from "react-query";
import * as yup from "yup";
function noop() {}
type FormProps<Data> = {
action: MutationResultPair<Data, Error, FormData, never | (() => void)>;
children(status: QueryStatus): ReactNode;
validation: yup.ObjectSchema;
@sergiodxa
sergiodxa / use-entity.ts
Created January 5, 2021 22:53
A React Query wrapper to fetch individual entities from a REST API
import { useQuery, QueryConfig } from "react-query";
type ID = string | number;
type Resource = { name: string; id: ID };
class APIClientError extends Error {}
class APIServerError extends Error {}
export async function getEntity<Entity = unknown>(
@sergiodxa
sergiodxa / til-querySelectorAll-scope.js
Created December 31, 2020 03:08
TIL: Al usar querySelector(All) desde un elemento es posible usar `:scope` para referirse a ese elemento en el selector de CSS, así podemos usar selectores como `>` para solo obtener hijos directos de nuestro elemento padre
/**
* Si tenemos este HTML
* <section id="some-section">
* <article> <h2>Article 1</h2> <article>A nested one</article> </article>
* <article> <h2>Article 2</h2> <article>A nested one</article> </article>
* <article> <h2>Article 3</h2> <article>A nested one</article> </article>
* </section>
*/
const section = document.querySelector("#some-section");
// Haciendo esto obtenemos seis artículos
@sergiodxa
sergiodxa / organized-component.tsx
Created August 9, 2020 01:12
How do I organize React components internally
function MyComponent(props) {
// refs
const $item = React.useRef();
// states
const [value, setValue] = React.useState("");
// computed
const filtered = React.useMemo(
() => props.list.filter((item) => item.includes(value)),
[props.list, value]
);
@sergiodxa
sergiodxa / react-feature-flags.js
Created October 24, 2019 17:55
React feature flags context, custom hook, hoc and render prop
import React from "react";
const FeatureFlags = React.createContext(null);
export function FeatureProvider({ features = null, children }) {
if (features === null || typeof features !== "object") {
throw new TypeError("The features prop must be an object or an array.");
}
return (
<FeatureFlags.Provider value={features}>{children}</FeatureFlags.Provider>