CLASSROOMIO-T-3: Make pages mobile friendly

This commit is contained in:
rotimi-best
2021-09-17 06:33:49 +03:00
parent 11d6b0616a
commit 2edfee4990
16 changed files with 152 additions and 82 deletions
@@ -101,6 +101,7 @@
frameborder="0" frameborder="0"
width="100%" width="100%"
height="569" height="569"
class="iframe"
allowfullscreen="true" allowfullscreen="true"
mozallowfullscreen="true" mozallowfullscreen="true"
webkitallowfullscreen="true" webkitallowfullscreen="true"
@@ -144,6 +145,7 @@
<iframe <iframe
width="100%" width="100%"
height="569" height="569"
class="iframe"
src={formatYoutubeVideo(url)} src={formatYoutubeVideo(url)}
title="YouTube video player" title="YouTube video player"
frameborder="0" frameborder="0"
@@ -161,3 +163,15 @@
</TabContent> </TabContent>
</slot:fragment> </slot:fragment>
</Tabs> </Tabs>
<style>
.iframe {
height: 569px;
}
@media (max-width: 760px) {
.iframe {
height: 209px;
}
}
</style>
@@ -24,6 +24,7 @@
import { course, group } from '../../store'; import { course, group } from '../../store';
import { updateCourse } from '../../../../utils/services/courses'; import { updateCourse } from '../../../../utils/services/courses';
import { profile } from '../../../../utils/store/user'; import { profile } from '../../../../utils/store/user';
import { isMobile } from '../../../../utils/store/useMobile';
// export let lessonId; // export let lessonId;
export let path; export let path;
@@ -34,6 +35,9 @@
function handleMainGroupClick(href) { function handleMainGroupClick(href) {
return () => { return () => {
if ($isMobile) {
show = false;
}
goto(href); goto(href);
}; };
} }
@@ -49,6 +53,11 @@
updateCourse($course.id, { title: $course.title }); updateCourse($course.id, { title: $course.title });
} }
function handleMobileChange(isMobile) {
if (isMobile) show = false;
else show = true;
}
onMount(() => { onMount(() => {
if (localStorage.getItem('hideCourseNav')) { if (localStorage.getItem('hideCourseNav')) {
show = localStorage.getItem('hideCourseNav') === 'false'; show = localStorage.getItem('hideCourseNav') === 'false';
@@ -66,6 +75,8 @@
}); });
}); });
$: handleMobileChange($isMobile);
$: { $: {
if (process.browser && show !== null) { if (process.browser && show !== null) {
localStorage.setItem('hideCourseNav', `${!show}`); localStorage.setItem('hideCourseNav', `${!show}`);
@@ -125,7 +136,9 @@
<Settings /> <Settings />
<div class="root z-10 {!show && 'hide'}"> <div
class="root z-10 {!show && 'hide'} {$isMobile ? 'fixed shadow-xl' : 'sticky'}"
>
{#if show} {#if show}
<div class="relative h-full"> <div class="relative h-full">
<PageNav bind:title={$course.title} paddingClass="pl-2"> <PageNav bind:title={$course.title} paddingClass="pl-2">
@@ -142,43 +155,47 @@
</RoleBasedSecurity> </RoleBasedSecurity>
</slot:fragment> </slot:fragment>
</PageNav> </PageNav>
{#each navItems as navItem} <div class="navItems">
{#if !navItem.show || (typeof navItem.show === 'function' && navItem.show($group.people, $profile.id))} {#each navItems as navItem}
<Expandable {#if !navItem.show || (typeof navItem.show === 'function' && navItem.show($group.people, $profile.id))}
label={navItem.label} <Expandable
handleClick={handleMainGroupClick(navItem.to)} label={navItem.label}
isGroupActive={(path || $page.path) === navItem.to} handleClick={handleMainGroupClick(navItem.to)}
hideSortIcon={navItem.hideSortIcon} isGroupActive={(path || $page.path) === navItem.to}
> hideSortIcon={navItem.hideSortIcon}
{#if navItem.isLecture} >
{#each $lessons as item, index} {#if navItem.isLecture}
<a {#each $lessons as item, index}
class="item flex items-center {(path || $page.path).includes( <a
item.id class="item flex items-center {(
) && 'active'} pl-7 py-2 {isStudent && !item.is_complete path || $page.path
? 'cursor-not-allowed' ).includes(item.id) && 'active'} pl-7 py-2 {isStudent &&
: ''}" !item.is_complete
href={isStudent && !item.is_complete ? 'cursor-not-allowed'
? $page.path : ''}"
: getLessonsRoute($course.id, item.id)} href={isStudent && !item.is_complete
> ? $page.path
<span class="course-counter"> : getLessonsRoute($course.id, item.id)}
{getLectureNo(index + 1)} on:click={() => $isMobile && (show = false)}
</span> >
<span>{item.title}</span> <span class="course-counter">
{#if item.is_complete} {getLectureNo(index + 1)}
<span class="ml-2 success">
<CheckmarkFilled20 class="carbon-icon" />
</span> </span>
{:else} <span>{item.title}</span>
<span class="text-md ml-2">🔒</span> {#if item.is_complete}
{/if} <span class="ml-2 success">
</a> <CheckmarkFilled20 class="carbon-icon" />
{/each} </span>
{/if} {:else}
</Expandable> <span class="text-md ml-2">🔒</span>
{/if} {/if}
{/each} </a>
{/each}
{/if}
</Expandable>
{/if}
{/each}
</div>
<div <div
class="w-full footer p-3 absolute bottom-2 flex items-center justify-between" class="w-full footer p-3 absolute bottom-2 flex items-center justify-between"
@@ -187,6 +204,7 @@
value="toggle" value="toggle"
onClick={() => goto('/courses')} onClick={() => goto('/courses')}
buttonClassName="mx-3" buttonClassName="mx-3"
size={$isMobile ? 'large' : 'small'}
> >
<Home32 class="carbon-icon" /> <Home32 class="carbon-icon" />
</IconButton> </IconButton>
@@ -223,7 +241,6 @@
flex-direction: column; flex-direction: column;
min-width: 360px; min-width: 360px;
max-width: 360px; max-width: 360px;
position: sticky;
top: 0; top: 0;
border-right: 1px solid var(--border-color); border-right: 1px solid var(--border-color);
background-color: rgb(250, 251, 252); background-color: rgb(250, 251, 252);
@@ -260,6 +277,11 @@
} }
} }
.navItems {
height: 82%;
overflow-y: scroll;
}
.toggler { .toggler {
right: -15px; right: -15px;
z-index: 10; z-index: 10;
@@ -268,4 +290,12 @@
height: fit-content; height: fit-content;
background: var(--border-color); background: var(--border-color);
} }
@media (max-width: 760px) {
.root {
width: 95%;
min-width: unset;
max-width: unset;
}
}
</style> </style>
+6 -1
View File
@@ -7,6 +7,7 @@
// import { questionnaireMetaData } from '../Course/components/Lesson/store/answers'; // import { questionnaireMetaData } from '../Course/components/Lesson/store/answers';
import { course } from '../Course/store'; import { course } from '../Course/store';
import Confetti from '../Confetti/index.svelte'; import Confetti from '../Confetti/index.svelte';
import { isMobile } from '../../utils/store/useMobile';
export let path = ''; export let path = '';
export let isExercisePage = false; export let isExercisePage = false;
@@ -33,7 +34,7 @@
<div class="root"> <div class="root">
<Navigation {path} /> <Navigation {path} />
<div class="rightBar"> <div class="rightBar" class:isMobile={$isMobile}>
{#if isExercisePage} {#if isExercisePage}
<Confetti /> <Confetti />
{/if} {/if}
@@ -51,4 +52,8 @@
flex-grow: 1; flex-grow: 1;
width: calc(100% - 360px); width: calc(100% - 360px);
} }
.rightBar.isMobile {
margin-left: 10px;
}
</style> </style>
+3 -1
View File
@@ -4,7 +4,9 @@
import { courses } from './store'; import { courses } from './store';
</script> </script>
<div class="flex items-center flex-wrap my-4 m-auto"> <div
class="flex items-center justify-center lg:justify-start flex-wrap my-4 m-auto"
>
{#each $courses as courseData} {#each $courses as courseData}
<Card <Card
id={courseData.id} id={courseData.id}
-3
View File
@@ -171,8 +171,5 @@
ul { ul {
align-items: center; align-items: center;
} }
li a {
display: none;
}
} }
</style> </style>
+1 -1
View File
@@ -1,7 +1,7 @@
<script> <script>
// import // import
// border border-gray-300 rounded-md p-3 bg-blue-200 bg-opacity-25 // border border-gray-300 rounded-md p-3 bg-blue-200 bg-opacity-25
export let width = 'max-w-3xl w-11/12'; export let width = 'max-w-3xl w-full lg:w-11/12';
export let padding = 'pb-5 px-4'; export let padding = 'pb-5 px-4';
export let className = ''; export let className = '';
</script> </script>
+6
View File
@@ -138,4 +138,10 @@
text-overflow: ellipsis; text-overflow: ellipsis;
padding: 10px; padding: 10px;
} }
@media (max-width: 760px) {
.title {
width: fit-content;
}
}
</style> </style>
@@ -60,7 +60,7 @@
<form on:submit|preventDefault={handleFormSubmit}> <form on:submit|preventDefault={handleFormSubmit}>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h2 class={!isNaN(grade) && 'w-3/4'}>{title}</h2> <h3 class={!isNaN(grade) && 'w-3/4'}>{title}</h3>
{#if !isNaN(grade)} {#if !isNaN(grade)}
<div class="flex items-center"> <div class="flex items-center">
<TextField <TextField
@@ -60,7 +60,7 @@
<form on:submit|preventDefault={handleFormSubmit}> <form on:submit|preventDefault={handleFormSubmit}>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h2 class={!isNaN(grade) && 'w-3/4'}>{title}</h2> <h3 class={!isNaN(grade) && 'w-3/4'}>{title}</h3>
{#if !isNaN(grade)} {#if !isNaN(grade)}
<div class="flex items-center"> <div class="flex items-center">
<TextField <TextField
@@ -35,7 +35,7 @@
<form on:submit|preventDefault={handleFormSubmit}> <form on:submit|preventDefault={handleFormSubmit}>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h2 class={!isNaN(grade) && 'w-3/4'}>{title}</h2> <h3 class={!isNaN(grade) && 'w-3/4'}>{title}</h3>
{#if !isNaN(grade)} {#if !isNaN(grade)}
<div class="flex items-center"> <div class="flex items-center">
<TextField <TextField
+11 -3
View File
@@ -19,6 +19,7 @@
import { handleAuthChange } from '../utils/functions/api'; import { handleAuthChange } from '../utils/functions/api';
import { user, profile } from '../utils/store/user'; import { user, profile } from '../utils/store/user';
import { getSupabase } from '../utils/functions/supabase'; import { getSupabase } from '../utils/functions/supabase';
import { isMobile } from '../utils/store/useMobile';
export let segment; export let segment;
export let config; export let config;
@@ -95,7 +96,13 @@
return /courses\/[a-z 0-9 -]/.test(path); return /courses\/[a-z 0-9 -]/.test(path);
} }
function handleResize() {
isMobile.update(() => window.innerWidth <= 760);
}
onMount(() => { onMount(() => {
handleResize();
const _isMvpUser = localStorage.getItem('mvp'); const _isMvpUser = localStorage.getItem('mvp');
console.log('mounting layout', isMvpUser, path, _isMvpUser); console.log('mounting layout', isMvpUser, path, _isMvpUser);
@@ -103,9 +110,9 @@
localStorage.setItem('mvp', 'true'); localStorage.setItem('mvp', 'true');
allowUser = true; allowUser = true;
} else if (!_isMvpUser) { } else if (!_isMvpUser) {
if (!!path) { // if (!!path) {
goto('/courses'); // goto('/courses');
} // }
return; return;
} }
@@ -134,6 +141,7 @@
$: path = $page.path.replace('/', ''); $: path = $page.path.replace('/', '');
</script> </script>
<svelte:window on:resize={handleResize} />
<Tailwindcss /> <Tailwindcss />
<!-- <Nav {segment} /> --> <!-- <Nav {segment} /> -->
-1
View File
@@ -104,7 +104,6 @@
} }
async function getCourses(userId) { async function getCourses(userId) {
console.log(`getCourses process.browser`, process.browser, cantFetch);
if (process.browser) { if (process.browser) {
if (cantFetch && typeof cantFetch === 'boolean' && !allCourses.length) { if (cantFetch && typeof cantFetch === 'boolean' && !allCourses.length) {
const updatedProfile = await setProfileIdOfGroupMember( const updatedProfile = await setProfileIdOfGroupMember(
+30 -26
View File
@@ -136,7 +136,7 @@
<PageBody padding="p-0"> <PageBody padding="p-0">
<section <section
class="w-11/12 py-3 px-4 m-auto lesson-list" class="w-full lg:w-11/12 py-3 px-3 lg:px-4 m-auto lesson-list"
use:dndzone={{ use:dndzone={{
items: $lessons, items: $lessons,
flipDurationMs, flipDurationMs,
@@ -179,7 +179,7 @@
<RoleBasedSecurity allowedRoles="[1,2]"> <RoleBasedSecurity allowedRoles="[1,2]">
<!-- Edit/Save --> <!-- Edit/Save -->
<div class="absolute top-2 right-0"> <div class="absolute -top-2 -right-2">
{#if lessonEditing === lesson.id} {#if lessonEditing === lesson.id}
<IconButton <IconButton
onClick={() => { onClick={() => {
@@ -226,31 +226,35 @@
</div> </div>
</div> --> </div> -->
<div class="flex items-center justify-between mt-6 w-full"> <div
{#if lessonEditing === lesson.id} class="flex items-start justify-between flex-col lg:flex-row lg:items-center mt-6 w-full"
<Select >
bind:value={lesson.profile} <div class="mb-3 lg:mb-0">
options={$group.tutors} {#if lessonEditing === lesson.id}
labelKey="fullname" <Select
/> bind:value={lesson.profile}
{:else if !lesson.profile} options={$group.tutors}
<p class="ml-2 text-sm">No tutor added</p> labelKey="fullname"
{:else}
<a href="." class="flex items-center hover:underline">
<img
alt="Placeholder"
class="block rounded-full"
width="24"
height="20"
src={lesson.profile.avatar_url}
/> />
<p class="ml-2 text-sm"> {:else if !lesson.profile}
{lesson.profile.fullname} <p class="ml-2 text-sm">No tutor added</p>
</p> {:else}
</a> <a href="." class="flex items-center hover:underline">
{/if} <img
alt="Placeholder"
class="block rounded-full"
width="24"
height="20"
src={lesson.profile.avatar_url}
/>
<p class="ml-2 text-sm">
{lesson.profile.fullname}
</p>
</a>
{/if}
</div>
<div class="flex items-cente"> <div class="flex items-center mb-3 lg:mb-0">
{#if lessonEditing === lesson.id} {#if lessonEditing === lesson.id}
<input <input
type="date" type="date"
@@ -267,7 +271,7 @@
{/if} {/if}
</div> </div>
<div class="flex items-center"> <div class="flex items-center mb-3 lg:mb-0">
{#if lessonEditing === lesson.id} {#if lessonEditing === lesson.id}
<TextField <TextField
bind:value={lesson.call_url} bind:value={lesson.call_url}
+3 -3
View File
@@ -54,7 +54,7 @@
</svelte:head> </svelte:head>
<div class="w-full h-screen flex items-center justify-center "> <div class="w-full h-screen flex items-center justify-center ">
<div class="container border border-gray-300 rounded-md p-12"> <div class="container border border-gray-300 rounded-md p-2 lg:p-12">
<form <form
on:submit|preventDefault={handleSubmit} on:submit|preventDefault={handleSubmit}
class="flex items-center flex-col w-full" class="flex items-center flex-col w-full"
@@ -103,8 +103,8 @@
</div> </div>
{#if !success} {#if !success}
<div class="my-4 w-full flex justify-between items-center"> <div class="my-4 w-full flex justify-end items-center">
<a href="/signup" class="text-blue-700 text-sm">Create an account</a> <!-- <a href="/login" class="text-blue-700 text-sm">Create an account</a> -->
<PrimaryButton <PrimaryButton
label={loading ? 'Creating...' : 'Next'} label={loading ? 'Creating...' : 'Next'}
type="submit" type="submit"
+4 -2
View File
@@ -121,9 +121,11 @@
<title>Profile of {currentProfile.username}</title> <title>Profile of {currentProfile.username}</title>
</svelte:head> </svelte:head>
<section class="root w-11/12 mt-3 m-auto flex items-start justify-between"> <section
class="root w-11/12 mt-3 m-auto flex items-start justify-between flex-col lg:flex-row"
>
{#if currentProfile.id} {#if currentProfile.id}
<div class="w-1/4 flex items-center flex-col"> <div class="w-full lg:w-1/4 flex items-center flex-col">
<!-- <img <!-- <img
alt={currentProfile.username} alt={currentProfile.username}
src={currentProfile.avatar_url} src={currentProfile.avatar_url}
+3
View File
@@ -0,0 +1,3 @@
import { writable } from 'svelte/store';
export const isMobile = writable(false);