View use-konami-code.jsx
import React, { useState, useEffect } from 'react'; | |
// Usage | |
function App(){ | |
// Call hook with function to fire off | |
// after konami code is entered. | |
useKonamiCode(() => { | |
alert('Good job 🥳'); | |
}); | |
View use-toggle.jsx
import { useState, useCallback } from "react"; | |
function useToggle(initialValue = false){ | |
// State with initial boolean value (true/false) | |
const [state, setState] = useState(initialValue); | |
// Let's create a toggle function | |
// This works, but we're using the state value from above | |
// instead of the current state. Usually they are the same, | |
// but if this hook was triggered multiple times rapidly then |
View use-toggle.jsx
import React, { useReducer } from "react"; | |
// Usage | |
function App(){ | |
const [isOn, toggleIsOn] = useToggle(); | |
return ( | |
<button onClick={toggleIsOn}> | |
Turn {isOn ? 'Off' : 'On'} | |
</button> |
View stripe-webhook.js
const getRawBody = require("raw-body"); | |
const { updateUserByCustomerId } = require("./_db.js"); | |
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY, { | |
apiVersion: process.env.STRIPE_API_VERSION, | |
}); | |
// Disable next.js body parsing (stripe needs the raw body to validate the event) | |
export const config = { | |
api: { |
View use-async-improved.jsx
import React, { useState, useEffect, useCallback } from 'react'; | |
// Hook | |
const useAsync = (asyncFunction, immediate = true) => { | |
const [status, setStatus] = useState('idle'); | |
const [value, setValue] = useState(null); | |
const [error, setError] = useState(null); | |
// The execute function wraps asyncFunction and | |
// handles setting state for pending, value, and error. |
View use-firestore-query.jsx
// Usage | |
function ProfilePage({ uid }) { | |
// Subscribe to Firestore document | |
const { data, status, error } = useFirestoreQuery( | |
firestore.collection("profiles").doc(uid) | |
); | |
if (status === "loading"){ | |
return "Loading..."; | |
} |
View OLD-use-firestore-query.jsx
// Usage | |
function ProfilePage({ uid }) { | |
// Subscribe to Firestore document | |
const { data, status, error } = useFirestoreQuery( | |
firestore.collection("profiles").doc(uid) | |
); | |
if (status === "loading"){ | |
return "Loading..."; | |
} |
View create-customer.js
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY); | |
const requireAuth = require("./_require-auth.js"); | |
const { updateUser } = require("./_db.js"); | |
export default requireAuth((req, res) => { | |
const user = req.user; | |
// If user already has a stripeCustomerId then return it in success response | |
if (user.stripeCustomerId) { | |
return res.send({ |
View use-firestore-query.jsx
// Usage | |
export function useUser(uid) { | |
return useQuery(uid && firestore.collection("users").doc(uid)); | |
} | |
// Custom useQuery hook for Firestore | |
function useQuery(query) { | |
const [queryState, setQueryState] = useState({ | |
status: "loading", | |
data: undefined, |
View firestore-rules
rules_version = '2'; | |
service cloud.firestore { | |
match /databases/{database}/documents { | |
match /users/{uid} { | |
allow read, write: if isUser(uid); | |
} | |
match /items/{id} { | |
allow read: if true; | |
//allow read: if isOwner(); // Would restrict reads to owner | |
allow delete: if isOwner(); |
NewerOlder