[+] Course page
This commit is contained in:
+17
-2
@@ -10,7 +10,13 @@ $c-green: rgb(88, 204, 2)
|
||||
$c-green-shadow: rgb(88, 167, 0)
|
||||
$c-red: rgb(255, 69, 58)
|
||||
$c-red-shadow: darken($c-red, 10%)
|
||||
$c-gold: rgb(255, 200, 0)
|
||||
$c-gold-flare: rgb(251, 233, 2)
|
||||
$c-gold-shadow: rgb(221, 164, 11)
|
||||
$c-gold-text: rgb(195, 126, 11)
|
||||
$c-white-shadow: rgb(222, 222, 222)
|
||||
$c-gray: rgb(229, 229, 229)
|
||||
$c-gray-shadow: rgb(175, 175, 175)
|
||||
$border-radius: 16px
|
||||
$shadow-width: 0 4px 0
|
||||
|
||||
@@ -78,6 +84,12 @@ button.white
|
||||
&.no-shadow
|
||||
border-width: 2px
|
||||
|
||||
.box.green
|
||||
border: none
|
||||
background-color: $c-green
|
||||
box-shadow: $shadow-width $c-green-shadow
|
||||
color: white
|
||||
|
||||
input
|
||||
@extend .box
|
||||
transition: all 0.2s ease-in-out
|
||||
@@ -109,13 +121,16 @@ h2
|
||||
|
||||
gap: 1em
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
&.non-center
|
||||
justify-content: flex-start
|
||||
|
||||
&.gap2
|
||||
gap: 2em
|
||||
|
||||
.page-pad
|
||||
padding: 2em 1em
|
||||
height: 100%
|
||||
|
||||
.navbar
|
||||
position: fixed
|
||||
@@ -201,4 +216,4 @@ h2
|
||||
.message.other
|
||||
align-self: flex-start
|
||||
background-color: $c-green
|
||||
border-radius: 0 20px 20px 20px
|
||||
border-radius: 0 20px 20px 20px
|
||||
|
||||
@@ -15,7 +15,7 @@ export interface Lang {
|
||||
icon: string
|
||||
}
|
||||
|
||||
export const possibleLangs = [
|
||||
export const possibleLangs: Lang[] = [
|
||||
{name: 'Mandarin Chinese', code: 'zh', icon: MandarinChinese},
|
||||
{name: 'Japanese', code: 'ja', icon: Japanese},
|
||||
{name: 'English', code: 'en', icon: English},
|
||||
@@ -53,17 +53,31 @@ export function isLoggedIn()
|
||||
return !!db.user
|
||||
}
|
||||
|
||||
export function getLanguage(username: string)
|
||||
{
|
||||
const users = JSON.parse(db.users)
|
||||
return users[username].language
|
||||
}
|
||||
|
||||
export function getUsername()
|
||||
{
|
||||
return db.user
|
||||
}
|
||||
|
||||
export function getLanguage(): Lang
|
||||
{
|
||||
const users = JSON.parse(db.users)
|
||||
const lang = users[getUsername()].language
|
||||
if (!lang)
|
||||
{
|
||||
alert('No language set, logging out')
|
||||
logout()
|
||||
window.location.href = '/'
|
||||
}
|
||||
const lang_obj = possibleLangs.find(l => l.name === lang)!
|
||||
if (!lang_obj)
|
||||
{
|
||||
alert(`Invalid language set: ${lang}, logging out`)
|
||||
logout()
|
||||
window.location.href = '/'
|
||||
}
|
||||
return lang_obj
|
||||
}
|
||||
|
||||
export interface CharacterChatCreationRequest
|
||||
{
|
||||
character: string;
|
||||
@@ -78,12 +92,12 @@ export interface CharacterChatCreationResponse
|
||||
|
||||
export async function startFictionalChat(character: string): Promise<CharacterChatCreationResponse> {
|
||||
const currUser = getUsername();
|
||||
const language = getLanguage(currUser);
|
||||
const language = getLanguage();
|
||||
|
||||
const request: CharacterChatCreationRequest = {
|
||||
character: character,
|
||||
user_name: currUser,
|
||||
language: language
|
||||
language: language.name
|
||||
};
|
||||
|
||||
const response = await fetch(`${backendUrl}/character-chat`, {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
@import "../index"
|
||||
|
||||
.course-button
|
||||
@extend button
|
||||
@extend .green
|
||||
|
||||
box-shadow: 0 8px 0 $c-green-shadow
|
||||
|
||||
width: 70px
|
||||
height: 60px
|
||||
border-radius: 50%
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
font-size: 5em
|
||||
overflow: hidden
|
||||
|
||||
&.gray
|
||||
background: $c-gray
|
||||
color: $c-gray-shadow
|
||||
box-shadow: 0 8px 0 $c-gray-shadow
|
||||
|
||||
&.gold
|
||||
background: $c-gold
|
||||
color: $c-gold-text
|
||||
box-shadow: 0 8px 0 $c-gold-shadow
|
||||
|
||||
|
||||
@@ -1,14 +1,66 @@
|
||||
import NavBar from "../components/NavBar"
|
||||
import {Icon} from "@iconify/react";
|
||||
import {getLanguage, isLoggedIn} from "../logic/sdk";
|
||||
import React from "react";
|
||||
import "./Course.sass"
|
||||
|
||||
export default function Course() {
|
||||
function CourseButton(props: {state: 'active' | 'locked' | 'completed', index: number})
|
||||
{
|
||||
let cs = 'course-button ' + {active: 'green', locked: 'gray', completed: 'gold'}[props.state];
|
||||
|
||||
return (
|
||||
<div className="v-layout p-10">
|
||||
<div className="flex flex-col flex-1">
|
||||
<h1>Course Page</h1>
|
||||
</div>
|
||||
<NavBar />
|
||||
const icon = {active: 'solar:star-bold', locked: 'solar:lock-bold', completed: 'mingcute:check-fill'}[props.state];
|
||||
|
||||
// Parameters for the sin wave
|
||||
const amplitude = 50; // Change this value to adjust the wave's height
|
||||
const frequency = 1; // Change this value to adjust the wave's frequency
|
||||
|
||||
// Calculate the horizontal translation
|
||||
const translateXValue = amplitude * Math.sin(props.index * frequency);
|
||||
|
||||
return (
|
||||
<div className={cs} style={{transform: `translateX(${translateXValue}px)`}}>
|
||||
<Icon icon={icon}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default function Course()
|
||||
{
|
||||
if (!isLoggedIn())
|
||||
{
|
||||
window.location.href = '/login';
|
||||
return <div></div>;
|
||||
}
|
||||
|
||||
// Get language
|
||||
const lang = getLanguage();
|
||||
|
||||
return (
|
||||
<div className="v-layout page-pad non-center">
|
||||
<div className="flex items-center justify-between font-bold">
|
||||
<img src={lang.icon} alt={lang.name} className="max-w-[50px]"/>
|
||||
<div className="flex items-center text-red-500 text-lg gap-2">
|
||||
<Icon icon="bi:fire" className="text-xl"/>
|
||||
<span>1</span>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
<div className="box green">
|
||||
<div>Chapter 1, Section 1</div>
|
||||
<div className="font-bold">Say hello and goodbye, use numbers</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div className="v-layout non-center items-center gap2">
|
||||
<CourseButton state={'completed'} index={0}/>
|
||||
<CourseButton state={'active'} index={1}/>
|
||||
<CourseButton state={'locked'} index={2}/>
|
||||
<CourseButton state={'locked'} index={3}/>
|
||||
<CourseButton state={'locked'} index={4}/>
|
||||
<CourseButton state={'locked'} index={5}/>
|
||||
</div>
|
||||
|
||||
<NavBar/>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ export default function Profile() {
|
||||
<div className="flex flex-col flex-1 h-full">
|
||||
<h1>Profile</h1>
|
||||
<h2>Username: {username}</h2>
|
||||
<h2>Currently Learning: {getLanguage(username)}</h2>
|
||||
<h2>Currently Learning: {getLanguage().name}</h2>
|
||||
<button className="red mt-auto mb-12" onClick={() => handleLougout()}>Logout</button>
|
||||
</div>
|
||||
<NavBar />
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function Review() {
|
||||
|
||||
const writtenReview = ["Questions", "Vocabulary"];
|
||||
const verbalReview = ["Questions", "Pronunciation"];
|
||||
const language = getLanguage(getUsername());
|
||||
const language = getLanguage().name;
|
||||
|
||||
const handleReviewLessonClick = (reviewType: string, lesson: string) => {
|
||||
type Question = { question: string, wordBank: string[], expected: string, type: string, exercise: string };
|
||||
|
||||
Reference in New Issue
Block a user