Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ yarn-error.log*

# vercel
.vercel

# we will ignore schema.gql
schema.gql
38 changes: 38 additions & 0 deletions components/SkillCard.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,47 @@
import { useCookies } from "react-cookie";
import {query as q} from 'faunadb';
import {client} from '../lib/client';
import { sanitized } from '../lib/skills';
import { gql } from 'graphql-request'
import { graphQLClient } from "../lib/client";

export default function SkillCard(skill, key) {
const [cookie] = useCookies(["guestUserId"])

const exam = async () => {

// get random 10 questions by topic
const response = await client.query(
q.Call(q.Function("get_random_questions"), sanitized(skill.skill))
)

// select question ids from question refs
const question_ids = response.map(ref => ref.id)

// generate Test with candidate GuestUser
const query = gql`
mutation CreateATest($skill: String!, $question_refs: [ID!], $candidate: ID!) {
createTest(
data: {
topic: $skill,
asks: { connect: $question_refs },
candidate: { connect: $candidate }
}
) {
_id
}
}
`;

const test = await graphQLClient(cookie.authToken).request(query, { skill: sanitized(skill.skill), question_refs: question_ids, candidate: cookie.guestUserId })
}

return (
<div className="card col-4 m-4" style={{width: '18rem'}} key={key}>
<div className="card-body">
<h5 className="card-title">{skill.skill}</h5>
<a className="btn btn-primary" href={'/quizes/'+encodeURIComponent(skill.skill)}>Test</a>
<button className="btn btn-secondary" onClick={exam}>Exam</button>
</div>
</div>
)
Expand Down
17 changes: 17 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import faunadb from 'faunadb';
import { GraphQLClient } from 'graphql-request';

export const client = new faunadb.Client({secret: process.env.NEXT_PUBLIC_FAUNA_GUEST_SECRET});

const endpoint = 'https://graphql.fauna.com/graphql';

// valid token to make request to fauandb will be stored in cookies.authToken
export const graphQLClient = (token) => {
const secret = token || process.env.NEXT_PUBLIC_FAUNA_GUEST_SECRET;

return new GraphQLClient(endpoint, {
headers: {
authorization: `Bearer ${secret}`,
},
});
};
2 changes: 1 addition & 1 deletion lib/skills.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function getAllSkillNames() {
}
}

const sanitized = (skillName) => encodeURIComponent(skillName.substring(1, skillName.length-1).toLowerCase())
export const sanitized = (skillName) => encodeURIComponent(skillName.substring(1, skillName.length-1).toLowerCase())

export async function getSkillQuizes(skillName) {
try {
Expand Down
15 changes: 15 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function getRandom(arr, n) {
var result = new Array(n),
len = arr.length,
taken = new Array(len);
if (n > len)
throw new RangeError("getRandom: more elements taken than available");
while (n--) {
var x = Math.floor(Math.random() * len);
result[n] = arr[x in taken ? taken[x] : x];
taken[x] = --len in taken ? taken[len] : len;
}
return result;
}

export {getRandom};
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@
},
"dependencies": {
"bootstrap": "^5.0.0-beta3",
"faunadb": "^4.5.2",
"gql": "^1.1.2",
"graphql": "^16.3.0",
"graphql-request": "^4.1.0",
"html-react-parser": "^1.2.6",
"next": "10.2.3",
"nextjs-cors": "^1.0.5",
"react": "17.0.2",
"react-cookie": "^4.1.1",
"react-dom": "17.0.2",
"remark": "^13.0.0",
"remark-html": "^13.0.1",
"remark-preset-lint-recommended": "^5.0.0"
"remark-preset-lint-recommended": "^5.0.0",
"swr": "^1.2.2"
}
}
58 changes: 57 additions & 1 deletion pages/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,68 @@
import Layout from "../components/Layout";
import {useState} from 'react'
import { useState, useEffect } from 'react'
import ListOfSkills from "../components/ListOfSkills";
import {getAllSkillNames} from "../lib/skills";
import {query as q} from 'faunadb';
import { useCookies } from "react-cookie";
import { client } from '../lib/client';

// get all methods with spread operator
const { Let, Select, Create, Collection, Tokens, Var, Update, Paginate, Match, Index } = q

export default function Home(props) {
const { skillNames } = props;
const [allSkills] = useState(skillNames);
const [skills, setSkills] = useState(skillNames)
const [guestUserId, setGuestUserId] = useState('')

const [cookie, setCookie, removeCookie] = useCookies(["guetUserToken"])

useEffect(async () => {
if (cookie.guestUserToken === undefined) {
try {
// make request to faunadb to create new token
const response = await client.query(
Let(
{
// create a new guestUser
ref: Select("ref", Create(Collection("GuestUser"))),
token: Select("secret", Create(Tokens(), { instance: Var("ref") }))
},
Update(Var("ref"), { data: { token: Var("token") } })
)
)

console.log(response)

// save the token associated with guest User in the cookie
setCookie("guestUserToken", response.data.token)
} catch(error) {
console.log(error)
}
} else {
// [TODO]: following code needs to execute even if guest User is freshly created
// then we have token to access the guest User
try {
// make request to faunadb to get the guest user ref
const response = await client.query(
Select("data",
Paginate(
Match(
Index("guest_user_by_token"),
cookie.guestUserToken
)
)
)
)

console.log(response[0].id)
setGuestUserId(response[0].id)
setCookie("guestUserId", response[0].id)
} catch(error) {
console.log(error)
}
}
}, [])


const search = (e) => {
Expand Down
Loading