Add course side nav with page navigation

This commit is contained in:
Ibitoye Rotimi Best
2021-05-08 11:47:18 +03:00
parent ae1f51684e
commit 026be1911f
29 changed files with 884 additions and 594 deletions
+4 -4
View File
@@ -3,6 +3,8 @@
export let className;
</script>
<p class={className ? className : "bg-set"}>{value}</p>
<style>
p {
display: inline-block;
@@ -18,9 +20,7 @@
}
.bg-set {
/* color: #586069;
background-color: #d1d5da80; */
color: #586069;
background-color: #d1d5da80;
}
</style>
<p class="{className} bg-set">{value}</p>
@@ -0,0 +1,108 @@
<script>
import { stores, goto } from "@sapper/app";
import Expandable from "../../Expandable/index.svelte";
import PageNav from "../../PageNav/index.svelte";
// export let lectureId;
const { page } = stores();
function handleMainGroupClick(href) {
return () => {
console.log("goto", href);
goto(href);
};
}
const lectures = [
{
title: "Lecture 1",
link: "/courses/1/lecture/1",
},
{
title: "Lecture 2",
link: "/courses/1/lecture/2",
},
{
title: "Lecture 3",
link: "/courses/1/lecture/3",
},
{
title: "Lecture 4",
link: "/courses/1/lecture/4",
},
{
title: "Lecture 5",
link: "/courses/1/lecture/5",
},
];
</script>
<div class="root">
<PageNav title="React.JS" />
<div>
<Expandable
label="Overview"
handleClick={handleMainGroupClick("/courses/1")}
isGroupActive={$page.path === "/courses/1"}
hideSortIcon
/>
<Expandable label="Lectures">
{#each lectures as lecture}
<a
class="item {(lecture.link === $page.path ||
!$page.path.length > 3) &&
'active'} pl-7 py-2"
href={lecture.link}
>
# <span>{lecture.title}</span>
</a>
{/each}
</Expandable>
<Expandable
label="People"
handleClick={handleMainGroupClick("/courses/1/people")}
isGroupActive={$page.path === "/courses/1/people"}
hideSortIcon
/>
<Expandable
label="Timetable"
handleClick={handleMainGroupClick("/courses/1/timetable")}
isGroupActive={$page.path === "/courses/1/timetable"}
hideSortIcon
/>
<Expandable
label="Scoreboard"
handleClick={handleMainGroupClick("/courses/1/score")}
isGroupActive={$page.path === "/courses/1/score"}
hideSortIcon
/>
<Expandable
label="Home tasks"
handleClick={handleMainGroupClick("/courses/1/hometasks")}
isGroupActive={$page.path === "/courses/1/hometasks"}
hideSortIcon
/>
</div>
</div>
<style>
.root {
height: 90vh;
display: flex;
flex-direction: column;
width: 250px;
position: sticky;
top: 0;
border-right: 1px solid var(--border-color);
overflow: auto;
}
.active {
background-color: #cae2f9;
border-left: 3px solid var(--main-primary-color);
padding-left: 0.85rem;
}
.item:hover {
background-color: #cae2f9;
}
</style>
@@ -0,0 +1,13 @@
<script>
import PageNav from "../../PageNav/index.svelte";
</script>
<div class="root">
<PageNav title="Home tasks" />
</div>
<style>
.root {
width: 100%;
}
</style>
@@ -0,0 +1 @@
<div>class work</div>
@@ -0,0 +1 @@
<div>Home workl</div>
@@ -0,0 +1,20 @@
<script>
import marked from "marked";
import readme from "../readme.js";
</script>
<!-- {@html marked(readme, {
breaks: true,
gfm: true,
})} -->
<iframe
title="Lecture"
src="https://docs.google.com/presentation/d/e/2PACX-1vTi_ATSrNBL-FMP7oDSi2DtXU7L8yzL0KAocNc-k7EqXaMM-oCbnbVmQjHYP0QKAw3r-QZayNfx5EpM/embed?start=false&loop=false&delayms=3000"
frameborder="0"
width="960"
height="569"
allowfullscreen="true"
mozallowfullscreen="true"
webkitallowfullscreen="true"
/>
@@ -0,0 +1,51 @@
<script>
import PageNav from "../../../PageNav/index.svelte";
import Classwork from "./Classwork.svelte";
import Homework from "./Homework.svelte";
import Readme from "./Readme.svelte";
export let path;
export let tab;
$: console.log("path", path);
</script>
<div>
<PageNav
navItems={[
{
label: "README.md",
isActive: tab === "lectures",
href: `${path}?tab=lectures`,
},
{
label: "Class work",
isActive: tab === "classwork",
href: `${path}?tab=classwork`,
},
{
label: "Hometasks",
isActive: tab === "hometasks",
href: `${path}?tab=hometasks`,
},
]}
/>
<div class="course">
{#if tab === "lectures"}
<Readme />
{:else if tab === "classwork"}
<Classwork />
{:else if tab === "hometasks"}
<Homework />
{/if}
</div>
</div>
<style>
.course {
max-width: 600px;
margin: 0 auto;
padding: 0 40px;
}
</style>
@@ -0,0 +1,13 @@
<script>
import PageNav from "../../PageNav/index.svelte";
</script>
<div class="root">
<PageNav title="People" />
</div>
<style>
.root {
width: 100%;
}
</style>
@@ -0,0 +1,13 @@
<script>
import PageNav from "../../PageNav/index.svelte";
</script>
<div class="root">
<PageNav title="Scoreboard" />
</div>
<style>
.root {
width: 100%;
}
</style>
@@ -0,0 +1,13 @@
<script>
import PageNav from "../../PageNav/index.svelte";
</script>
<div class="root">
<PageNav title="Time table" />
</div>
<style>
.root {
width: 100%;
}
</style>
+38
View File
@@ -0,0 +1,38 @@
<script>
import marked from "marked";
import PageNav from "../PageNav/index.svelte";
const readme = `
# Introduction
Welcome to this course, we are glad you made it here
## What you'l learn
1. Build powerful, fast, user-friendly and reactive web apps.
2. Provide amazing user experiences by leveraging the power of JavaScript with ease.
3. Apply for high-paid jobs or work as a freelancer in one the most-demanded sectors you can find in web dev right now.
4. Learn all about React Hooks and React Components.
`;
</script>
<div class="root">
<PageNav title="Overview" />
<div class="body">
{@html marked(readme, {
breaks: true,
gfm: true,
})}
</div>
</div>
<style>
.root {
width: 100%;
}
.body {
max-width: 600px;
margin: 10px;
}
</style>
@@ -1,75 +0,0 @@
<script>
import marked from "marked";
import Education16 from "carbon-icons-svelte/lib/Education16";
import Catalog16 from "carbon-icons-svelte/lib/Catalog16";
import readme from "./readme.js";
// export let lectures = [
// "Today",
// "Yesterday",
// "April 24, 2021",
// "April 17, 2021",
// "March 25, 2021",
// ];
</script>
<div class="course">
{@html marked(readme, {
breaks: true,
gfm: true,
})}
<!-- {#each lectures as lecture, key}
<p class="lesson-date">{lecture}</p>
<div class="lecture">
<h4 class="lecture-title text-blue-700">
<a rel="prefetch" href="courses/1">Lecture {lectures.length - key}</a>
</h4>
<p>
Here is some description about the course that you should know. It will
begin on the first and end on the second of the next month.
</p>
<div class="flex mt-3 mb-2">
<span class="flex mr-2"
><Education16 class="mr-2" />
5</span
>
<span class="flex"
><Catalog16 class="mr-2" />
20</span
>
</div>
</div>
{/each} -->
</div>
<style>
/* .lesson-date {
margin: 10px 10px 5px;
color: #171717;
font-size: 0.875rem;
font-weight: 400;
} */
.course {
max-width: 600px;
margin: 0 auto;
padding: 0 40px;
}
/* .lecture {
border: 1px solid var(--border-color);
padding: 15px;
margin-bottom: 20px;
border-radius: 6px;
}
.lecture-title {
width: fit-content;
font-size: 18px;
}
span {
color: #586069;
font-size: 12px;
width: 40px;
} */
</style>
@@ -1,74 +0,0 @@
<script>
import { stores } from "@sapper/app";
import Expandable from "../../Expandable/index.svelte";
import PageNav from "../../PageNav/index.svelte";
// export let lectureId;
const { page } = stores();
function handleLecturesClick(goTo) {
return () => {
console.log("goto", goTo);
};
}
const lectures = [
{
title: "Lecture 1",
link: "/courses/1/lecture/1",
},
{
title: "Lecture 2",
link: "/courses/1/lecture/2",
},
{
title: "Lecture 3",
link: "/courses/1/lecture/3",
},
{
title: "Lecture 4",
link: "/courses/1/lecture/4",
},
{
title: "Lecture 5",
link: "/courses/1/lecture/5",
},
];
</script>
<div class="root">
<PageNav title="React.JS" />
<div>
<Expandable
label="Lectures"
handleClick={handleLecturesClick("/courses/1/lecture/1")}
>
{#each lectures as lecture}
<a
class="{(lecture.link === $page.path || !$page.path.length > 3) &&
'active'} pl-4 py-2"
href={lecture.link}
>
# <span>{lecture.title}</span>
</a>
{/each}
</Expandable>
</div>
</div>
<style>
.root {
height: 90vh;
display: flex;
flex-direction: column;
width: 250px;
position: sticky;
top: 0;
border-right: 1px solid var(--border-color);
overflow: auto;
}
.active {
background-color: #cae2f9;
border-left: 3px solid var(--main-primary-color);
}
</style>
+30 -7
View File
@@ -4,6 +4,9 @@
let isExpanded = true;
export let handleClick = () => {};
export let label = "";
export let hideSortIcon = false;
export let isGroupActive = false;
// export let subMenuItems = [];
function onClick() {
isExpanded = !isExpanded;
@@ -13,18 +16,25 @@
<div>
<div
class="relative flex items-center"
class="item relative flex items-center {isGroupActive && 'active'}"
role="button"
tabindex="0"
on:click={onClick}
>
<CaretSortDown20
class="carbon-icon-sort {isExpanded ? '' : 'carbon-icon-minimize'}"
/>
<span class="ml-6 mb-2 {isExpanded ? 'font-bold' : ''}">{label}</span>
{#if !hideSortIcon}
<CaretSortDown20
class="carbon-icon-sort {isExpanded ? '' : 'carbon-icon-minimize'}"
/>
{/if}
<span class="pl-6 py-2 font-bold">{label}</span>
</div>
{#if isExpanded}
<div class="flex flex-col">
<!-- {#each subMenuItems as item}
<a class="item {item.isActive && 'active'} pl-6 py-2" href={item.link}>
# <span>{item.title}</span>
</a>
{/each} -->
<slot />
</div>
{/if}
@@ -33,12 +43,25 @@
<style>
:global(svg.carbon-icon-sort) {
position: absolute;
top: -5px;
top: 3px;
left: 0;
}
:global(svg.carbon-icon-minimize) {
transform: rotate(270deg);
top: 2px;
top: 10px;
left: -6px;
}
.active {
background-color: #cae2f9;
border-left: 3px solid var(--main-primary-color);
}
.active span {
padding-left: 1.3rem;
}
.item:hover {
background-color: #cae2f9;
}
</style>
-1
View File
@@ -1,5 +1,4 @@
<script>
import NewQuestion from "../NewQuestion/index.svelte";
import Forum32 from "carbon-icons-svelte/lib/Forum32";
import SendAlt32 from "carbon-icons-svelte/lib/SendAlt32";
import Catalog32 from "carbon-icons-svelte/lib/Catalog32";
@@ -1,13 +1,15 @@
<script>
import AddComment20 from "carbon-icons-svelte/lib/AddComment20";
import AddAlt32 from "carbon-icons-svelte/lib/AddAlt32";
export let href;
export let label = "";
</script>
<a
class="root bg-blue-700 hover:bg-blue-900 text-white font-bold py-3 px-8 rounded inline-flex items-center float-right"
href="/ask"
class="root bg-blue-700 hover:bg-blue-900 text-white font-bold py-2 px-4 rounded inline-flex items-center float-right"
{href}
>
<AddComment20 class="carbon-icon fill-current w-4 h-4 mr-2" />
<span>Спросить</span>
<AddAlt32 class="carbon-icon fill-current w-4 h-4 mr-1" />
{label}
</a>
<style>
@@ -20,9 +22,6 @@
a {
padding: 10px 15px;
}
a span {
display: none;
}
a :global(svg.carbon-icon) {
margin-right: 0;
+7 -1
View File
@@ -1,13 +1,16 @@
<script>
import NewButton from "../NewButton/index.svelte";
export let title = "";
export let navItems = [];
export let addButtonHref;
export let addButtonLabel;
let dynamicRootClass = "";
$: dynamicRootClass =
Array.isArray(navItems) && navItems.length > 4 ? "bring-down" : "";
</script>
<div class="header flex justify-between mb-2 {dynamicRootClass}">
<div class="header flex items-center justify-between mb-2 {dynamicRootClass}">
{#if !!title}
<h4 class="title">{title}</h4>
{/if}
@@ -18,6 +21,9 @@
{item.label}
</a>
{/each}
{#if addButtonHref}
<NewButton href={addButtonHref} label={addButtonLabel} />
{/if}
</div>
{/if}
</div>
+10
View File
@@ -0,0 +1,10 @@
<script>
export let label;
export let className = "";
</script>
<button
class="bg-blue-700 hover:bg-blue-900 text-white font-bold py-1 px-3 rounded {className}"
>
{label}
</button>
+7 -1
View File
@@ -3,8 +3,14 @@
@tailwind components;
@tailwind utilities;
h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: revert;
font-weight: revert;
margin: 0.8em 0;
}
</style>
+60 -58
View File
@@ -1,16 +1,71 @@
<script>
import marked from 'marked';
import marked from "marked";
import PrimaryButton from "../PrimaryButton/index.svelte";
let isWriteMode = true;
export let value = ``;
export let placeholder = ``;
const activeClassName = 'border-b-2 border-blue-700';;
const activeClassName = "border-b-2 border-blue-700";
const handleTabClick = tab => event => {
isWriteMode = tab === 1
}
const handleTabClick = (tab) => (event) => {
isWriteMode = tab === 1;
};
</script>
<div class="root mt-5 border border-gray rounded-md">
<div class="p-2 pb-0">
<button
on:click={handleTabClick(1)}
class="focus:outline-none p-2 {isWriteMode && `${activeClassName}`}"
>
Write
</button>
<button
on:click={handleTabClick(2)}
class="focus:outline-none p-2 {!isWriteMode && `${activeClassName}`}"
>
Preview
</button>
</div>
<div class="m-2 mb-0 p-0">
{#if isWriteMode}
<textarea
bind:value
{placeholder}
class="border border-gray rounded-md p-2"
/>
{:else}
<article class="preview prose prose-sm sm:prose p-2">
{@html marked(value)}
</article>
{/if}
</div>
{#if !isWriteMode}
<hr />
{/if}
<div class="flex justify-between items-center px-2 pb-1">
<div class="flex items-center text-sm">
<svg
class="octicon mr-2"
height="16"
viewBox="0 0 16 16"
version="1.1"
width="16"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"
/>
</svg>
<span>Styling with Markdown is supported</span>
</div>
<PrimaryButton label="Answer" />
</div>
</div>
<style>
.root {
width: 100%;
@@ -32,56 +87,3 @@
fill: currentColor;
}
</style>
<div class="root mt-5 border border-gray rounded-md">
<div class="p-2 pb-0">
<button
on:click={handleTabClick(1)}
class="focus:outline-none p-2 {isWriteMode && `${activeClassName}`}"
>
Write
</button>
<button
on:click={handleTabClick(2)}
class="focus:outline-none p-2 {!isWriteMode && `${activeClassName}`}"
>
Preview
</button>
</div>
<div class="m-2 mb-0 p-0">
{#if isWriteMode}
<textarea
bind:value
placeholder="{placeholder}"
class="border border-gray rounded-md p-2"
></textarea>
{:else}
<article class="preview prose prose-sm sm:prose p-2">
{@html marked(value)}
</article>
{/if}
</div>
{#if !isWriteMode}
<hr>
{/if}
<div class="flex justify-between items-center px-2 pb-1">
<div class="flex items-center text-sm">
<svg
class="octicon mr-2"
height="16"
viewBox="0 0 16 16"
version="1.1"
width="16"
aria-hidden="true"
>
<path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path>
</svg>
<span>Styling with Markdown is supported</span>
</div>
<button class="bg-blue-700 hover:bg-blue-900 text-white font-bold py-1 px-3 rounded">
Answer
</button>
</div>
</div>
+28
View File
@@ -0,0 +1,28 @@
<script>
</script>
<figure class="md:flex bg-gray-100 rounded-xl p-8 md:p-0">
<img
class="w-32 h-32 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto"
src="https://tailwindcss.com/sarah-dayan.jpg"
alt=""
width="384"
height="512"
/>
<div class="pt-6 md:p-8 text-center md:text-left space-y-4">
<blockquote>
<p class="text-lg font-semibold">
“Tailwind CSS is the only framework that I've seen scale on large teams.
It’s easy to customize, adapts to any design, and the build size is
tiny.”
</p>
</blockquote>
<figcaption class="font-medium">
<div class="text-cyan-600">Sarah Dayan</div>
<div class="text-gray-500">Staff Engineer, Algolia</div>
</figcaption>
</div>
</figure>
<style>
</style>