Skip to content

Commit

Permalink
Merge pull request #574 from logto-io/gao-add-react-query-smaple
Browse files Browse the repository at this point in the history
feat: add react-query sample
  • Loading branch information
gao-sun authored Nov 13, 2023
2 parents cd5ad7d + 71c8220 commit ec81675
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/next-app-dir-sample/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const metadata: Metadata = {
},
};

const RootLayout = ({ children }: { children: React.ReactNode }) => {
const RootLayout = ({ children }: { readonly children: React.ReactNode }) => {
return (
<html lang="en">
<body>{children}</body>
Expand Down
2 changes: 1 addition & 1 deletion packages/next-app-dir-sample/app/nav.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

type Props = {
isAuthenticated: boolean;
readonly isAuthenticated: boolean;
};

const Nav = ({ isAuthenticated }: Props) => {
Expand Down
11 changes: 10 additions & 1 deletion packages/next-sample/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ import { SWRConfig } from 'swr';

import fetchJson from '../libraries/fetch-json';

const MyApp = ({ Component, pageProps }: AppProps) => {
/**
* Monkey-patch the AppProps since it is annoying to match the exact version of `@types/react`.
* @see https://stackoverflow.com/questions/71809903/next-js-component-cannot-be-used-as-a-jsx-component
*/
type PatchedAppProps = Omit<AppProps, 'Component'> & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readonly Component: any;
};

const MyApp = ({ Component, pageProps }: PatchedAppProps) => {
return (
<SWRConfig
value={{
Expand Down
2 changes: 1 addition & 1 deletion packages/next-sample/pages/profile-ssr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useMemo } from 'react';
import { logtoClient } from '../libraries/logto';

type Props = {
user: LogtoContext;
readonly user: LogtoContext;
};

const ProfileSsr = ({ user }: Props) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-server-actions-sample/app/callback/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { handleSignIn } from "../../libraries/logto";
import { useEffect } from "react";

type Props = {
searchParams: Record<string, string>;
readonly searchParams: Record<string, string>;
};

export default function Callback({ searchParams }: Props) {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-server-actions-sample/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const metadata: Metadata = {
export default function RootLayout({
children,
}: {
children: React.ReactNode;
readonly children: React.ReactNode;
}) {
return (
<html lang="en">
Expand Down
1 change: 1 addition & 0 deletions packages/react-sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@logto/react": "workspace:^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.3",
"react-router-dom": "^6.2.2"
},
"devDependencies": {
Expand Down
5 changes: 5 additions & 0 deletions packages/react-sample/src/App.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ body {
button {
cursor: pointer;
}

li {
text-align: left;
margin: 0.5rem 0;
}
14 changes: 5 additions & 9 deletions packages/react-sample/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { appId, endpoint } from './consts';
import Callback from './pages/Callback';
import Home from './pages/Home';
import ProtectedResource from './pages/ProtectedResource';

import './App.module.scss';
import ReactQuery from './pages/ReactQuery';

export const App = () => {
const config: LogtoConfig = {
Expand All @@ -22,14 +22,10 @@ export const App = () => {
<Routes>
<Route path="/" element={<Home />} />
<Route path="/callback" element={<Callback />} />
<Route
path="/protected-resource"
element={
<RequireAuth>
<ProtectedResource />
</RequireAuth>
}
/>
<Route path="/protected" element={<RequireAuth />}>
<Route index element={<ProtectedResource />} />
<Route path="react-query" element={<ReactQuery />} />
</Route>
</Routes>
</LogtoProvider>
</BrowserRouter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useLogto } from '@logto/react';
import { useEffect } from 'react';
import { Outlet } from 'react-router-dom';

import { redirectUrl } from './consts';

const RequireAuth = ({ children }: { children: JSX.Element }) => {
const RequireAuth = () => {
const { isAuthenticated, isLoading, signIn } = useLogto();

useEffect(() => {
Expand All @@ -12,7 +13,7 @@ const RequireAuth = ({ children }: { children: JSX.Element }) => {
}
}, [isAuthenticated, isLoading, signIn]);

return isAuthenticated ? children : null;
return isAuthenticated ? <Outlet /> : <p>Not authenticated</p>;
};

export default RequireAuth;
17 changes: 12 additions & 5 deletions packages/react-sample/src/pages/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Home = () => {

return (
<div className={styles.container}>
<h3>Logto React Sample</h3>
<h3>Logto React sample</h3>
{!isAuthenticated && (
<>
<button
Expand All @@ -30,15 +30,15 @@ const Home = () => {
void signIn(redirectUrl);
}}
>
Sign In
Sign in
</button>
<button
type="button"
onClick={() => {
void signIn(redirectUrl, 'signUp');
}}
>
Sign Up
Sign up
</button>
</>
)}
Expand All @@ -49,7 +49,7 @@ const Home = () => {
void signOut(baseUrl);
}}
>
Sign Out
Sign out
</button>
)}
{isAuthenticated && user && (
Expand All @@ -70,7 +70,14 @@ const Home = () => {
))}
</tbody>
</table>
<Link to="/protected-resource">View Protected Resource</Link>
<ul>
<li>
<Link to="/protected">View protected resource</Link>
</li>
<li>
<Link to="/protected/react-query">View user info via react-query</Link>
</li>
</ul>
</>
)}
</div>
Expand Down
71 changes: 71 additions & 0 deletions packages/react-sample/src/pages/ReactQuery/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useLogto } from '@logto/react';
import { useQuery, QueryClient, QueryClientProvider } from 'react-query';

import { endpoint } from '../../consts';

/**
* A custom hook that returns a fetcher function that automatically adds the access token to the
* request. It uses `fetch` under the hood, and has the same signature.
*/
const useApi = () => {
const { getAccessToken } = useLogto();
const fetcher: typeof fetch = async (input, init) => {
const accessToken = await getAccessToken();

if (!accessToken) {
throw new Error('No access token available.');
}

const response = await fetch(input, {
...init,
headers: {
...init?.headers,
Authorization: `Bearer ${accessToken}`,
},
});
return response;
};

return fetcher;
};

const queryClient = new QueryClient();

const ReactQuery = () => {
return (
<QueryClientProvider client={queryClient}>
<Content />
</QueryClientProvider>
);
};

const Content = () => {
const api = useApi();
const query = useQuery('userinfo', async () => {
const response = await api(new URL('/oidc/me', endpoint));
return response.json();
});

if (query.isLoading) {
return <div>Loading...</div>;
}

if (query.isError) {
return (
<div>
<h1>Error</h1>
<p>{JSON.stringify(query.error)}</p>
</div>
);
}

return (
<div>
<h1>Success</h1>
<p>You are seeing this page because react-query successfully fetched the user info.</p>
<p>{JSON.stringify(query.data)}</p>
</div>
);
};

export default ReactQuery;
5 changes: 4 additions & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@
"react": ">=16.8.0"
},
"eslintConfig": {
"extends": "@silverhand/react"
"extends": "@silverhand/react",
"rules": {
"react/prefer-read-only-props": "off"
}
},
"prettier": "@silverhand/eslint-config/.prettierrc",
"publishConfig": {
Expand Down
Loading

0 comments on commit ec81675

Please sign in to comment.