├── examples ├── 2024-08-17-memoization │ ├── .gitignore │ ├── package.json │ ├── example-1.js │ ├── example-2.js │ ├── example-3.js │ ├── package-lock.json │ ├── example-5.ts │ └── example-4.ts ├── 2024-08-09-redux-basics │ ├── .eslintrc.json │ ├── jsconfig.json │ ├── next.config.mjs │ ├── src │ │ └── app │ │ │ ├── favicon.ico │ │ │ ├── hooks.js │ │ │ ├── store-provider.js │ │ │ ├── layout.js │ │ │ ├── user-profile-container.js │ │ │ ├── user-profile-component.js │ │ │ ├── store.js │ │ │ ├── globals.css │ │ │ ├── example-reducer.js │ │ │ ├── page.js │ │ │ ├── page-2.js │ │ │ ├── user-profile.js │ │ │ ├── page-3.js │ │ │ └── store-2.js │ ├── postcss.config.mjs │ ├── prettier.config.js │ ├── .gitignore │ ├── tailwind.config.js │ ├── public │ │ ├── vercel.svg │ │ └── next.svg │ ├── package.json │ ├── README.md │ └── eslint.config.mjs ├── 2024-06-24-complex-navigation-expo │ ├── hooks │ │ ├── useColorScheme.ts │ │ ├── useColorScheme.web.ts │ │ └── useThemeColor.ts │ ├── assets │ │ ├── images │ │ │ ├── icon.png │ │ │ ├── favicon.png │ │ │ ├── splash.png │ │ │ ├── react-logo.png │ │ │ ├── adaptive-icon.png │ │ │ ├── react-logo@2x.png │ │ │ ├── react-logo@3x.png │ │ │ └── partial-react-logo.png │ │ └── fonts │ │ │ └── SpaceMono-Regular.ttf │ ├── babel.config.js │ ├── .prettierignore │ ├── tsconfig.json │ ├── app │ │ ├── (login) │ │ │ ├── _layout.tsx │ │ │ ├── (auth) │ │ │ │ ├── register.tsx │ │ │ │ ├── _layout.tsx │ │ │ │ └── index.tsx │ │ │ └── forgot-password.tsx │ │ ├── (main) │ │ │ ├── (home) │ │ │ │ ├── _layout.tsx │ │ │ │ ├── details.tsx │ │ │ │ ├── options.tsx │ │ │ │ └── index.tsx │ │ │ ├── settings.tsx │ │ │ └── _layout.tsx │ │ ├── +not-found.tsx │ │ ├── +html.tsx │ │ └── _layout.tsx │ ├── components │ │ ├── __tests__ │ │ │ ├── ThemedText-test.tsx │ │ │ └── __snapshots__ │ │ │ │ └── ThemedText-test.tsx.snap │ │ ├── navigation │ │ │ └── TabBarIcon.tsx │ │ ├── ThemedView.tsx │ │ ├── ExternalLink.tsx │ │ ├── HelloWave.tsx │ │ ├── Collapsible.tsx │ │ ├── ThemedText.tsx │ │ └── ParallaxScrollView.tsx │ ├── .prettier.config.js │ ├── eslint.config.mjs │ ├── constants │ │ └── Colors.ts │ ├── app.json │ ├── README.md │ ├── package.json │ └── scripts │ │ └── reset-project.js ├── 2024-08-20-redux-saga │ ├── src │ │ ├── app │ │ │ ├── dashboard │ │ │ │ └── page.js │ │ │ ├── login │ │ │ │ └── page.js │ │ │ ├── favicon.ico │ │ │ ├── layout.js │ │ │ └── globals.css │ │ ├── lib │ │ │ └── utils.js │ │ ├── features │ │ │ ├── dashboard │ │ │ │ ├── dashboard-page-component.js │ │ │ │ └── dashboard-page-container.js │ │ │ ├── user-profiles │ │ │ │ ├── user-profile-api.js │ │ │ │ ├── user-profile-saga.js │ │ │ │ └── user-profile-reducer.js │ │ │ ├── example │ │ │ │ ├── example-saga.js │ │ │ │ └── example-reducer.js │ │ │ └── user-authentication │ │ │ │ ├── user-authentication-page-container.js │ │ │ │ └── user-authentication-page-component.js │ │ ├── redux │ │ │ ├── root-saga.js │ │ │ ├── store-provider.js │ │ │ ├── root-reducer.js │ │ │ ├── store.js │ │ │ ├── effects.js │ │ │ └── saga-middleware.js │ │ ├── hocs │ │ │ └── with-router.js │ │ └── components │ │ │ └── ui │ │ │ ├── label.jsx │ │ │ ├── input.jsx │ │ │ ├── card.jsx │ │ │ └── button.jsx │ ├── jsconfig.json │ ├── next.config.mjs │ ├── postcss.config.mjs │ ├── components.json │ ├── prettier.config.js │ ├── .gitignore │ ├── public │ │ ├── vercel.svg │ │ └── next.svg │ ├── tsconfig.json │ ├── .eslintrc.json │ ├── package.json │ ├── README.md │ └── tailwind.config.js ├── 2024-07-16-set-up-next-js-production │ ├── .husky │ │ ├── pre-commit │ │ └── prepare-commit-msg │ ├── next.config.mjs │ ├── src │ │ ├── app │ │ │ ├── favicon.ico │ │ │ ├── [lang] │ │ │ │ ├── page.tsx │ │ │ │ └── layout.tsx │ │ │ ├── login │ │ │ │ ├── page.tsx │ │ │ │ └── counter-component.tsx │ │ │ └── globals.css │ │ ├── features │ │ │ ├── internationalization │ │ │ │ ├── i18n-config.ts │ │ │ │ ├── dictionaries │ │ │ │ │ └── en-US.json │ │ │ │ ├── use-switch-locale-href.ts │ │ │ │ ├── get-dictionaries.ts │ │ │ │ └── localization-middleware.ts │ │ │ ├── user-authentication │ │ │ │ └── example.test.tsx │ │ │ └── user-profile │ │ │ │ └── user-profile-model.ts │ │ ├── lib │ │ │ ├── utils.ts │ │ │ └── prisma.ts │ │ ├── tests │ │ │ ├── setup-test-environment.ts │ │ │ └── react-test-utils.tsx │ │ └── middleware.ts │ ├── postcss.config.mjs │ ├── playwright │ │ └── example.spec.ts │ ├── components.json │ ├── prettier.config.js │ ├── prisma │ │ ├── schema.prisma │ │ └── seed.ts │ ├── public │ │ ├── vercel.svg │ │ └── next.svg │ ├── .gitignore │ ├── tsconfig.json │ ├── vitest.config.ts │ ├── README.md │ ├── eslint.config.mjs │ ├── playwright.config.ts │ ├── tailwind.config.ts │ ├── package.json │ └── .github │ │ └── workflows │ │ └── pull-request.yml ├── 2024-09-01-redux-for-production │ ├── next.config.mjs │ ├── src │ │ ├── redux │ │ │ ├── clear.ts │ │ │ ├── hooks.ts │ │ │ ├── root-saga.ts │ │ │ ├── store-provider.tsx │ │ │ ├── root-reducer.ts │ │ │ └── store.ts │ │ ├── app │ │ │ ├── favicon.ico │ │ │ ├── dashboard │ │ │ │ └── page.ts │ │ │ ├── posts │ │ │ │ └── page.ts │ │ │ ├── login │ │ │ │ └── page.ts │ │ │ ├── layout.tsx │ │ │ └── globals.css │ │ ├── features │ │ │ ├── posts │ │ │ │ ├── posts-types.ts │ │ │ │ ├── posts-page-component.tsx │ │ │ │ ├── posts-api.ts │ │ │ │ ├── posts-list-component.tsx │ │ │ │ └── add-post-component.tsx │ │ │ ├── user-profiles │ │ │ │ ├── user-profiles-types.ts │ │ │ │ ├── user-profiles-api.ts │ │ │ │ ├── user-profiles-saga.ts │ │ │ │ └── user-profiles-reducer.ts │ │ │ ├── user-authentication │ │ │ │ ├── user-authentication-api.ts │ │ │ │ ├── user-authentication-container.ts │ │ │ │ ├── user-authentication-reducer.ts │ │ │ │ ├── user-authentication-saga.ts │ │ │ │ └── user-authentication-component.tsx │ │ │ ├── app-loading │ │ │ │ ├── app-loading-component.tsx │ │ │ │ ├── app-loading-saga.ts │ │ │ │ ├── app-loading-reducer.ts │ │ │ │ └── app-loading-container.tsx │ │ │ └── dashboard │ │ │ │ ├── dashboard-page-container.tsx │ │ │ │ └── dashboard-page-component.tsx │ │ ├── hocs │ │ │ ├── public-page.ts │ │ │ ├── authenticated-page.ts │ │ │ ├── redirect-if-logged-in.ts │ │ │ ├── with-loading.ts │ │ │ ├── with-auth.ts │ │ │ ├── requires-permission │ │ │ │ ├── requires-permission-component.tsx │ │ │ │ └── index.ts │ │ │ ├── hoist-statics.ts │ │ │ └── redirect.tsx │ │ ├── lib │ │ │ └── utils.ts │ │ └── components │ │ │ ├── spinner.tsx │ │ │ └── ui │ │ │ ├── label.tsx │ │ │ ├── input.tsx │ │ │ ├── button.tsx │ │ │ └── card.tsx │ ├── postcss.config.mjs │ ├── prettier.config.js │ ├── components.json │ ├── .gitignore │ ├── public │ │ ├── vercel.svg │ │ └── next.svg │ ├── tsconfig.json │ ├── .eslintrc.json │ ├── README.md │ ├── package.json │ └── tailwind.config.ts └── 2024-07-04-master-higher-order-components │ ├── with-layout.jsx │ ├── layout.jsx │ └── with-layout.test.jsx ├── .gitignore └── README.md /examples/2024-08-17-memoization/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | examples/2024-06-24-complex-navigation-expo/.gitignore -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/hooks/useColorScheme.ts: -------------------------------------------------------------------------------- 1 | export { useColorScheme } from "react-native"; 2 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/app/dashboard/page.js: -------------------------------------------------------------------------------- 1 | export { default } from '../../features/dashboard/dashboard-page-container'; 2 | -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/app/login/page.js: -------------------------------------------------------------------------------- 1 | export { default } from '../../features/user-authentication/user-authentication-page-container'; 2 | -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-08-20-redux-saga/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-08-09-redux-basics/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm run lint && npm run type-check 5 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/redux/clear.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from '@reduxjs/toolkit'; 2 | 3 | export const clear = createAction('all/clear'); 4 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-09-01-redux-for-production/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/.husky/prepare-commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | exec < /dev/tty && npx cz --hook || true 5 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/icon.png -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-07-16-set-up-next-js-production/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/features/posts/posts-types.ts: -------------------------------------------------------------------------------- 1 | export type Post = { 2 | userId: number; 3 | id: number; 4 | title: string; 5 | body: string; 6 | }; 7 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/favicon.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/splash.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ["babel-preset-expo"], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jan Hesters & ReactSquad Tutorials 2 | 3 | In this repository, you can find all code examples and resources for the Jan Hesters' and ReactSquad's tutorials on YouTube, X, LinkedIn etc. 4 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/react-logo.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/adaptive-icon.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/react-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/react-logo@2x.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/react-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/react-logo@3x.png -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/fonts/SpaceMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/fonts/SpaceMono-Regular.ttf -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/lib/utils.js: -------------------------------------------------------------------------------- 1 | import { clsx } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/hocs/public-page.ts: -------------------------------------------------------------------------------- 1 | import { compose } from '@reduxjs/toolkit'; 2 | 3 | import withLoading from './with-loading'; 4 | 5 | export default compose(withLoading); 6 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/assets/images/partial-react-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EarlyNode/tutorials/HEAD/examples/2024-06-24-complex-navigation-expo/assets/images/partial-react-logo.png -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/2024-06-24-complex-navigation-expo/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | yarn.lock 4 | package-lock.json 5 | public 6 | coverage 7 | templates 8 | build 9 | playwright-report 10 | test-results 11 | .expo -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/src/features/internationalization/i18n-config.ts: -------------------------------------------------------------------------------- 1 | export const i18n = { 2 | defaultLocale: 'en-US', 3 | locales: ['en-US'], 4 | } as const; 5 | 6 | export type Locale = (typeof i18n)['locales'][number]; 7 | -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /examples/2024-07-16-set-up-next-js-production/src/features/internationalization/dictionaries/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "counter": { 3 | "decrement": "Decrement", 4 | "increment": "Increment" 5 | }, 6 | "landing": { 7 | "welcome": "Welcome" 8 | } 9 | } -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/features/dashboard/dashboard-page-component.js: -------------------------------------------------------------------------------- 1 | export function DashboardPageComponent({ currentUsersEmail }) { 2 | return ( 3 |
User not found.
17 | )} 18 |Email: {email}
5 | ) : ( 6 | 14 | )} 15 |Current locale: {lang}
16 |This text is rendered on the server: {dictionary.landing.welcome}
17 |15 | This component is rendered on client: 16 | 19 | {count} 20 | 23 |
24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/src/app/store.js: -------------------------------------------------------------------------------- 1 | import { 2 | applyMiddleware, 3 | combineReducers, 4 | legacy_createStore as createStore, 5 | } from 'redux'; 6 | import logger from 'redux-logger'; 7 | import { thunk } from 'redux-thunk'; 8 | 9 | import { 10 | reducer as exampleReducer, 11 | slice as exampleSlice, 12 | } from './example-reducer'; 13 | import { 14 | reducer as userProfileReducer, 15 | slice as userProfileSlice, 16 | } from './user-profile'; 17 | 18 | const rootReducer = combineReducers({ 19 | [exampleSlice]: exampleReducer, 20 | [userProfileSlice]: userProfileReducer, 21 | }); 22 | 23 | export const makeStore = () => { 24 | return createStore( 25 | rootReducer, 26 | rootReducer(), 27 | applyMiddleware(thunk, logger), 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/features/user-authentication/user-authentication-page-container.js: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { connect } from 'react-redux'; 4 | import { compose } from 'redux'; 5 | 6 | import { withRouter } from '../../hocs/with-router'; 7 | import { 8 | loginClicked, 9 | selectIsLoading, 10 | } from '../user-profiles/user-profile-reducer'; 11 | import { UserAuthenticationPageComponent } from './user-authentication-page-component'; 12 | 13 | const mapStateToProps = state => ({ 14 | isLoading: selectIsLoading(state), 15 | }); 16 | 17 | const mapDispatchToProps = { 18 | onLoginClicked: loginClicked, 19 | }; 20 | 21 | export default compose( 22 | withRouter, 23 | connect(mapStateToProps, mapDispatchToProps), 24 | )(UserAuthenticationPageComponent); 25 | -------------------------------------------------------------------------------- /examples/2024-08-09-redux-basics/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | 29 | @layer utilities { 30 | .text-balance { 31 | text-wrap: balance; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/components/ui/input.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '../../lib/utils'; 4 | 5 | const Input = React.forwardRef(({ className, type, ...props }, ref) => { 6 | return ( 7 | 16 | ); 17 | }); 18 | Input.displayName = 'Input'; 19 | 20 | export { Input }; 21 | -------------------------------------------------------------------------------- /examples/2024-09-01-redux-for-production/src/features/app-loading/app-loading-container.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { useEffect } from 'react'; 3 | import type { ConnectedProps } from 'react-redux'; 4 | import { connect } from 'react-redux'; 5 | 6 | import { AppLoadingComponent } from './app-loading-component'; 7 | import { loadApp } from './app-loading-saga'; 8 | 9 | const mapDispatchToProps = { loadApp }; 10 | 11 | const connector = connect(undefined, mapDispatchToProps); 12 | 13 | type AppLoadingPropsFromRedux = ConnectedPropsCount: {count}
17 | 18 | 26 |Count: {count}
14 | 15 | 23 |{post.body}
43 |Current Count: {currentCount}
; 40 | } 41 | 42 | export const selectCurrentUserId = state => state[slice].currentUserId; 43 | 44 | export const selectUsers = state => state[slice].users; 45 | 46 | export const selectCurrentUser = state => 47 | state[slice].users[state[slice].currentUserId]; 48 | 49 | export const selectCurrentUsersEmail = state => 50 | state[slice].users[state[slice].currentUserId]?.email ?? ''; 51 | 52 | export const selectCurrentUsersFullName = state => 53 | `${state[slice].users[state[slice].currentUserId]?.firstName ?? ''} ${state[slice].users[state[slice].currentUserId]?.lastName ?? ''}`; 54 | 55 | export const selectIsLoggedIn = state => Boolean(state[slice].currentUserId); 56 | -------------------------------------------------------------------------------- /examples/2024-08-20-redux-saga/src/features/user-authentication/user-authentication-page-component.js: -------------------------------------------------------------------------------- 1 | import { Button } from '../../components/ui/button'; 2 | import { 3 | Card, 4 | CardContent, 5 | CardDescription, 6 | CardFooter, 7 | CardHeader, 8 | CardTitle, 9 | } from '../../components/ui/card'; 10 | import { Input } from '../../components/ui/input'; 11 | import { Label } from '../../components/ui/label'; 12 | 13 | export function UserAuthenticationPageComponent({ 14 | isLoading, 15 | onLoginClicked, 16 | router, 17 | }) { 18 | return ( 19 |{title}
; 8 | } 9 | 10 | describe('withLayout', () => { 11 | test('given a component: returns the component with a default title', () => { 12 | const WrappedComponent = withLayout()(MyComponent); 13 | 14 | render(