Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
568 changes: 502 additions & 66 deletions client/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"proxy": "http://127.0.0.1:5000/",
"dependencies": {
"@descope/react-sdk": "^1.0.3",
"@descope/react-sdk": "^2.27.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand Down
50 changes: 50 additions & 0 deletions client/src/ConfigError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';

const PLACEHOLDERS = new Set([
'',
'YOUR_DESCOPE_PROJECT_ID',
'__ProjectID__',
'your-project-id',
]);

export function isValidDescopeProjectId(value) {
if (typeof value !== 'string') return false;
const id = value.trim();
if (!id) return false;
if (PLACEHOLDERS.has(id)) return false;
return true;
}

export default function ConfigError() {
return (
<div
style={{
fontFamily: 'system-ui, sans-serif',
maxWidth: 520,
margin: '48px auto',
padding: 24,
lineHeight: 1.5,
}}
>
<h1 style={{ fontSize: '1.25rem' }}>Descope configuration required</h1>
<p>
Add your project ID to <code style={{ background: '#eee', padding: '2px 6px' }}>client/.env</code>:
</p>
<pre
style={{
background: '#f4f4f4',
padding: 12,
borderRadius: 8,
overflow: 'auto',
}}
>
REACT_APP_PROJECT_ID=P2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</pre>
<p>
Use the same value as in the Descope console (Settings → Project). Then stop and restart{' '}
<code style={{ background: '#eee', padding: '2px 6px' }}>npm start</code> — Create React App only reads{' '}
<code style={{ background: '#eee', padding: '2px 6px' }}>.env</code> at startup.
</p>
</div>
);
}
107 changes: 70 additions & 37 deletions client/src/components/Dashboard.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,93 @@
import '../App.css';
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import { getSessionToken } from '@descope/react-sdk'

import { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { getSessionToken, useSession } from '@descope/react-sdk';

function Dashboard() {
const sessionToken = getSessionToken(); // get the session token
const navigate = useNavigate()
const { isSessionLoading, isAuthenticated, sessionToken } = useSession();
const navigate = useNavigate();
const [roles, setRoles] = useState({
teacherRole: false,
studentRole: false
})
studentRole: false,
});

useEffect(() => {
fetch('/get_role_data', { // call the api endpoint from the flask server
if (isSessionLoading) return;
if (!isAuthenticated) {
navigate('/login');
return;
}

const token = sessionToken || getSessionToken();
if (!token) {
navigate('/login');
return;
}

fetch('/get_role_data', {
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + sessionToken,
}
}).then(data => {
if (data.status === 401) {
navigate('/login')
}
return data.json()
}).then(jsonData => {
setRoles({
teacherRole: jsonData.valid_teacher,
studentRole: jsonData.valid_student
})
}).catch((err) => {
console.log(err)
navigate('/login')
Authorization: `Bearer ${token}`,
},
})
}, [])
.then((data) => {
if (data.status === 401) {
navigate('/login');
return null;
}
return data.json();
})
.then((jsonData) => {
if (!jsonData) return;
setRoles({
teacherRole: jsonData.valid_teacher,
studentRole: jsonData.valid_student,
});
})
.catch(() => {
navigate('/login');
});
}, [isSessionLoading, isAuthenticated, sessionToken, navigate]);

if (isSessionLoading) {
return (
<div className="page">
<p>Loading...</p>
</div>
);
}

if (!isAuthenticated) {
return null;
}

return (
<div className='page'>
<h1 className='title'>Dashboard</h1>
<Link className='link btn' to="/profile">Profile</Link>
<div className="page">
<h1 className="title">Dashboard</h1>
<Link className="link btn" to="/profile">
Profile
</Link>
{roles.teacherRole && (
<div className='page'>
<div className="page">
<h1>Welcome back Teacher!</h1>
<p className='students'>You have 50+ students currently 🧑‍🎓</p>
<p className="students">You have 50+ students currently 🧑‍🎓</p>
</div>
)}
{roles.studentRole && (
<div className='page'>
<div className="page">
<h1>Welcome back Student!</h1>
<p className='student'>Unlucky! You have homework!</p>
<iframe src="https://giphy.com/embed/H9UeFGxZz4cBG" width="469" height="480" allowFullScreen></iframe>
<p className="student">Unlucky! You have homework!</p>
<iframe
title="Homework gif"
src="https://giphy.com/embed/H9UeFGxZz4cBG"
width="469"
height="480"
allowFullScreen
/>
</div>
)}
</div>
)
);
}


export default Dashboard;
export default Dashboard;
44 changes: 27 additions & 17 deletions client/src/components/Home.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import '../App.css';
import { useEffect } from "react";
import { Link } from "react-router-dom";
import { useSession } from '@descope/react-sdk'
import { useNavigate } from "react-router-dom";
import { Link, Navigate } from 'react-router-dom';
import { useSession } from '@descope/react-sdk';

function Home() {
const { isAuthenticated } = useSession()
const navigate = useNavigate()
const { isAuthenticated, isSessionLoading } = useSession();

useEffect(() => {
if (isAuthenticated) {
return navigate("/profile");
}
}, [isAuthenticated]) // listen for when isAuthenticated has changed
if (isSessionLoading) {
return (
<div className="page">
<p>Loading...</p>
</div>
);
}

if (isAuthenticated) {
return <Navigate to="/profile" replace />;
}

return (
<div className='page'>
<h1 className='title'>Home</h1>
<Link className='link btn' to="/login">Login</Link>
<iframe src="https://giphy.com/embed/bKj0qEKTVBdF2o5Dgn" width="480" height="352" allowFullScreen></iframe>
<div className="page">
<h1 className="title">Home</h1>
<Link className="link btn" to="/login">
Login
</Link>
<iframe
title="Welcome animation"
src="https://giphy.com/embed/bKj0qEKTVBdF2o5Dgn"
width="480"
height="352"
allowFullScreen
/>
</div>
)
);
}


export default Home;
69 changes: 37 additions & 32 deletions client/src/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,50 @@
import '../App.css';
import React, { useEffect } from "react";
import { Descope, useSession, useUser } from '@descope/react-sdk'
import { useNavigate } from "react-router-dom";

import React, { useEffect } from 'react';
import { Descope, useSession, useUser } from '@descope/react-sdk';
import { useNavigate } from 'react-router-dom';

function Login() {
// isAuthenticated: boolean - is the user authenticated?
// isSessionLoading: boolean - Use this for showing loading screens while objects are being loaded
const { isAuthenticated, isSessionLoading } = useSession()
// isUserLoading: boolean - Use this for showing loading screens while objects are being loaded
const { isUserLoading } = useUser()
const navigate = useNavigate()
const { isAuthenticated, isSessionLoading } = useSession();
const { isUserLoading } = useUser();
const navigate = useNavigate();

useEffect(() => {
if (isAuthenticated) {
return navigate("/profile");
navigate('/profile');
}
}, [isAuthenticated]) // listen for when isAuthenticated has changed
}, [isAuthenticated, navigate]);

return (
<div className='page'>
{
(isSessionLoading || isUserLoading) && <p>Loading...</p>
}
if (isSessionLoading || isUserLoading) {
return (
<div className="page">
<p>Loading...</p>
</div>
);
}

if (isAuthenticated) {
return (
<div className="page">
<p>Loading...</p>
</div>
);
}

{!isAuthenticated &&
(
<>
<h1 className='title'>Login/SignUp to see the Secret Message!</h1>
<Descope
flowId="sign-up-or-in"
onSuccess = {(e) => console.log(e.detail.user)}
onError={(e) => console.log('Could not log in!')}
theme="light"
/>
</>
)
}
return (
<div className="page">
<h1 className="title">Login/SignUp to see the Secret Message!</h1>
<Descope
flowId="sign-up-or-in"
theme="light"
onSuccess={(e) => {
console.log(e.detail.user);
}}
onError={(err) => {
console.log('Error!', err);
}}
/>
</div>
)
);
}


export default Login;
Loading
Loading