kopia lustrzana https://github.com/learn-awesome/learndb
commit
fe72a4a7a0
|
@ -11,6 +11,7 @@
|
|||
|
||||
function resetQuery(){
|
||||
query = '';
|
||||
showSearch =false;
|
||||
}
|
||||
|
||||
$: query && fetch(`/learn/items.json?_shape=array&name__contains=${query}&_size=6`)
|
||||
|
|
|
@ -96,7 +96,11 @@
|
|||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="nav">
|
||||
<NavButtonWithLabel isActive={currentView === "/topics"} target="#/topics" label="Topics">
|
||||
<NavButtonWithLabel
|
||||
isActive={currentView === "/topics"}
|
||||
target="#/topics"
|
||||
label="Topics"
|
||||
>
|
||||
<LibraryIcon class=" flex-shrink-0 h-6 w-6"/>
|
||||
</NavButtonWithLabel>
|
||||
|
||||
|
@ -104,17 +108,17 @@
|
|||
<ViewGridIcon class=" flex-shrink-0 h-6 w-6"/>
|
||||
</NavButtonWithLabel>
|
||||
|
||||
<a href="#/randomtopic" on:click={getRandomTopicName} class={(currentView === "/randomtopic" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " w-full hover:dark:bg-darkPrimaryBg group flex justify-start gap-3 items-center py-5 pl-4 text-sm font-medium"}>
|
||||
<a href="#/randomtopic" on:click={getRandomTopicName} class={(currentView === "/randomtopic" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " w-full hover:bg-lightBg hover:dark:text-darkPrimary hover:dark:bg-darkBg hover:text-lightPrimary group flex justify-start gap-3 items-center py-5 pl-4 text-sm font-medium"}>
|
||||
<GiftIcon class=" flex-shrink-0 h-6 w-6"/>
|
||||
<h3 class="text-center">Random Topic</h3>
|
||||
</a>
|
||||
|
||||
<a href="#/randomitem" on:click={getRandomItemId} class={(currentView === "/randomitem" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " w-full hover:dark:bg-darkPrimaryBg group flex justify-start gap-3 items-center py-5 pl-4 text-sm font-medium"}>
|
||||
<a href="#/randomitem" on:click={getRandomItemId} class={(currentView === "/randomitem" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " w-full hover:bg-lightBg hover:dark:text-darkPrimary hover:dark:bg-darkBg hover:text-lightPrimary group flex justify-start gap-3 items-center py-5 pl-4 text-sm font-medium"}>
|
||||
<GiftIcon class=" flex-shrink-0 h-6 w-6"/>
|
||||
<h3 class="text-center">Random Item</h3>
|
||||
</a>
|
||||
|
||||
<button on:click="{e => showSearch = true}" class={(currentView === "/search" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " hover:dark:bg-darkPrimaryBg w-full group flex justify-start gap-3 items-center py-5 text-sm font-medium pl-4"}>
|
||||
<button on:click="{e => showSearch = true}" class={(currentView === "/search" ? 'bg-lightPrimCont text-lightPrimary dark:bg-darkPrimCont dark:text-darkPrimary' : '') + " hover:bg-lightBg hover:dark:text-darkPrimary hover:dark:bg-darkBg hover:text-lightPrimary w-full group flex justify-start gap-3 items-center py-5 text-sm font-medium pl-4"}>
|
||||
<SearchIcon class=" flex-shrink-0 h-6 w-6"/>
|
||||
<h3 class="text-center"> Search</h3>
|
||||
</button>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
relative inline-flex flex-nowrap items-center px-4 py-2
|
||||
{i == 0 && 'rounded-l-md'}
|
||||
{i == tabs.length-1 && 'rounded-r-md'}
|
||||
border border-gray-800 text-sm font-medium focus:z-10 focus:outline-none
|
||||
border border-gray-800 text-sm font-medium hover:scale-x-105 focus:z-10 focus:outline-none
|
||||
{currentlySelected === i? 'bg-lightTertiary text-lightBg dark:bg-darkTertiary dark:text-darkBg' : 'bg-lightPrimCont text-lightPrimary'}
|
||||
"
|
||||
>
|
||||
|
|
|
@ -8,24 +8,6 @@
|
|||
let item;
|
||||
let reviews = [];
|
||||
|
||||
function youtube_parser(url){
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
return (match&&match[7].length==11)? match[7] : false;
|
||||
}
|
||||
|
||||
function get_thumbnail_image_url(item){
|
||||
let youtubeformat = item.links.split(";").find(s => s.startsWith('video|') && (s.includes('youtube.com') || s.includes('youtu.be')));
|
||||
let youtubeurl = youtubeformat && youtubeformat.split('|')[1];
|
||||
let ytid = youtubeurl && youtube_parser(youtubeurl);
|
||||
let thumbnail_image_url = ytid && `https://img.youtube.com/vi/${ytid}/mqdefault.jpg`
|
||||
return thumbnail_image_url
|
||||
}
|
||||
|
||||
function get_tld(url){
|
||||
return (new URL(url)).hostname.replace('www.','');
|
||||
}
|
||||
|
||||
$: fetch(`/learn/items/${itemid}.json?_shape=object`)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
|
@ -47,20 +29,46 @@
|
|||
bookmarks.set(newobj)
|
||||
}
|
||||
|
||||
let oEmded_image_ytb_url = null;
|
||||
|
||||
function oEmded_image(item){
|
||||
let youtubeformat = item.links.split(";").find(s => s.startsWith('video|') && (s.includes('youtube.com') || s.includes('youtu.be')));
|
||||
let youtubeurl = youtubeformat && youtubeformat.split('|')[1];
|
||||
|
||||
if(!youtubeurl) return;
|
||||
|
||||
return `https://www.youtube.com/oembed?url=${youtubeurl}&format=json`
|
||||
}
|
||||
|
||||
$: item && item.links.includes('video|') && oEmded_image(item) && fetch(oEmded_image(item))
|
||||
.then( r => r.json())
|
||||
.then(data => {
|
||||
oEmded_image_ytb_url = data.thumbnail_url
|
||||
});
|
||||
|
||||
|
||||
function wikiUrlForEmbed(item){
|
||||
var wikiurl = item.links.split(";").find((l) => l.includes('wiki|')).split('|')[1];
|
||||
return wikiurl.replace('simple.wikipedia.org/','simple.m.wikipedia.org/').replace('en.wikipedia.org/','en.m.wikipedia.org/');
|
||||
}
|
||||
|
||||
// function youtube_parser(url){
|
||||
// var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
||||
// var match = url.match(regExp);
|
||||
// return (match&&match[7].length==11)? match[7] : false;
|
||||
// }
|
||||
|
||||
// function get_thumbnail_image_url(item){
|
||||
// let youtubeformat = item.links.split(";").find(s => s.startsWith('video|') && (s.includes('youtube.com') || s.includes('youtu.be')));
|
||||
// let youtubeurl = youtubeformat && youtubeformat.split('|')[1];
|
||||
// let ytid = youtubeurl && youtube_parser(youtubeurl);
|
||||
// let thumbnail_image_url = ytid && `https://img.youtube.com/vi/${ytid}/mqdefault.jpg`
|
||||
// return thumbnail_image_url
|
||||
// }
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line-clamp{
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
.scroll{
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgb(31 41 55);
|
||||
|
@ -79,7 +87,7 @@
|
|||
|
||||
{#if item}
|
||||
|
||||
<div class="max-w-4xl mx-auto border shadow-2xl px-20 py-8 rounded-xl mt-20">
|
||||
<div class="max-w-4xl mx-auto border shadow-2xl px-20 py-8 rounded-xl mt-20 bg-white font-sans">
|
||||
<h3 class="my-2">
|
||||
{#each item.topics.split(";") as topicname}
|
||||
<a href={"#/topic/" + topicname} class="mr-2 font-bold">{topicname.toUpperCase()}</a>
|
||||
|
@ -88,26 +96,29 @@
|
|||
<div class="mt-10">
|
||||
<div class="mb-10 flex flex-col sm:flex-row md:flex-col lg:flex-row">
|
||||
<div class="flex-nowrap">
|
||||
|
||||
{#if item.image}
|
||||
<div class="mr-5">
|
||||
<img class="mr-6 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl " src="{item.image}" alt="{item.name}" />
|
||||
<div class="mr-10">
|
||||
<img class="mr-28 mb-6 w-44 h-64 transform rounded-md shadow-lg transition duration-300 ease-out hover:scale-105 md:shadow-xl " src="{item.image}" alt="{item.name}" />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- {:else if item.links.includes('book')}
|
||||
<img class="mr-6 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl" src="/static/book-cover.png" alt="{item.name}" />
|
||||
<img class="mr-6 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl" src="/static/book-cover.png" alt="{item.name}" /> -->
|
||||
|
||||
{:else if item.links.includes('video')}
|
||||
<div class="relative">
|
||||
<img class="h-28 w-44 flex justify-center items-center border-r border-gray-500 relative" src="{get_thumbnail_image_url(item)}" alt="{item.name}">
|
||||
{:else if item.links.includes('video') }
|
||||
<div class="relative mr-5 rounded-lg overflow-hidden shadow-lg">
|
||||
<div class="w-80 h-60 bg-lightPrimary">
|
||||
<img class="h-auto w-80 flex justify-center items-center border-r border-gray-500 relative" src="{oEmded_image_ytb_url}" alt="{item.name}">
|
||||
</div>
|
||||
<div class="absolute inset-0 w-full h-full flex items-center justify-center" aria-hidden="true">
|
||||
<svg class="h-12 w-12 text-indigo-500" fill="currentColor" viewBox="0 0 84 84"><circle opacity="0.9" cx="42" cy="42" r="42" fill="white"></circle><path d="M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z"></path></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<img class="mr-6 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl" src="/static/book-cover.png" alt="{item.name}" /> -->
|
||||
|
||||
{:else if !item.links.includes('video') && item.links.includes('book')}
|
||||
<div class="mr-10 shadow-lg">
|
||||
<img class="mr-28 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl" src="/static/book-cover.png" alt="{item.name}" />
|
||||
</div>
|
||||
{/if}
|
||||
<!-- <img class="mr-6 mb-6 w-44 h-64 transform rounded-md shadow-md transition duration-300 ease-out hover:scale-105 md:shadow-xl" src="{item.image || '/static/book-cover.png'}" alt="" /> -->
|
||||
</div>
|
||||
|
@ -167,8 +178,8 @@
|
|||
<!-- Description -->
|
||||
{#if item.description}
|
||||
<section class="my-8">
|
||||
<h2 class="text-base font-bold ">Description</h2>
|
||||
<p class="mt-4 text-sm max-w-lg">{item.description}</p>
|
||||
<h2 class="font-bold text-lg">Description</h2>
|
||||
<p class="mt-4 tracking-wide">{item.description}</p>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
|
@ -245,7 +256,7 @@
|
|||
{#if reviews.length > 0}
|
||||
<section class="my-8">
|
||||
<div class="flex justify-between items-center">
|
||||
<h2 class="text-base font-bold text-gray-100">Reviews</h2>
|
||||
<h2 class="text-base font-bold">Reviews</h2>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col md:flex-row md:overflow-x-auto md:pb-5 mt-3 gap-2 scroll">
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
{#if format.id == 'book'}
|
||||
<sl-tab-panel name={format.id} active={i == 0}>
|
||||
<div class="grid gap-5 grid-cols-2 sm:grid-cols-3 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 justify-items-center">
|
||||
<div class="grid gap-5 grid-cols-1 sm:grid-cols-2 md:grid-cols-1 lg:grid-cols-3 xl:grid-cols-4 justify-items-center">
|
||||
{#each items.filter(x => x.links.includes(format.id + '|')) as item}
|
||||
<BookCard {item}/>
|
||||
{/each}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
export let label;
|
||||
export let target;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
export let review: any;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line-clamp {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<article class="px-3 py-4 bg-lightSecondary2 text-lightSecondary1 dark:bg-darkSecondary2 dark:text-darkSecondary1 rounded-lg text-xs w-48 max-w-sm shrink-0">
|
||||
<h3 class="font-semibold">{review.blurb.toString().slice(0,10)}...</h3>
|
||||
<p class="mt-2 line-clamp">{review.blurb}</p>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
</script>
|
||||
|
||||
<form class="w-full p-2 inline-flex flex-wrap" on:submit|preventDefault>
|
||||
<form class="w-full p-2 gap-3 mt-12 inline-flex flex-wrap" on:submit|preventDefault>
|
||||
<sl-input type="search" placeholder="Search by keywords" size="medium" clearable class="flex-1 border-0 p-0 focus:ring-0" value={query.text} on:sl-input="{e => query.text = e.target.value}">
|
||||
<sl-icon name="search" slot="prefix"></sl-icon>
|
||||
</sl-input>
|
||||
|
@ -32,7 +32,7 @@
|
|||
</fluent-combobox>
|
||||
{/if}
|
||||
|
||||
<sl-select class="ml-2 w-52" on:sl-change="{e => query.tag = e.target.value}" value={query.tag}>
|
||||
<sl-select class="w-52" on:sl-change="{e => query.tag = e.target.value}" value={query.tag}>
|
||||
<sl-menu-item value="">Any tag</sl-menu-item>
|
||||
<sl-menu-item value="inspirational">Inspirational</sl-menu-item>
|
||||
<sl-menu-item value="educational">Educational</sl-menu-item>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<sl-menu-item value="oer">Open (no login or pay)</sl-menu-item>
|
||||
</sl-select>
|
||||
|
||||
<sl-select class="ml-2 w-44" on:sl-change="{e => query.level = e.target.value}" value={query.level}>
|
||||
<sl-select class="w-44" on:sl-change="{e => query.level = e.target.value}" value={query.level}>
|
||||
<sl-menu-item value="">Any level</sl-menu-item>
|
||||
<sl-menu-item value="childlike">Childlike</sl-menu-item>
|
||||
<sl-menu-item value="beginner">Beginner</sl-menu-item>
|
||||
|
@ -52,7 +52,7 @@
|
|||
<sl-menu-item value="research">Research</sl-menu-item>
|
||||
</sl-select>
|
||||
|
||||
<sl-select class="ml-2 w-52" on:sl-change="{e => query.sortby = e.target.value}" value={query.sortby}>
|
||||
<sl-select class="w-52" on:sl-change="{e => query.sortby = e.target.value}" value={query.sortby}>
|
||||
<sl-icon name="sort-down-alt" slot="prefix"></sl-icon>
|
||||
<sl-menu-item value="rating">Sort by Rating</sl-menu-item>
|
||||
<sl-menu-item value="year">Sort by Year</sl-menu-item>
|
||||
|
|
|
@ -19,19 +19,19 @@
|
|||
oEmded_image_ytb_url = data.thumbnail_url
|
||||
});
|
||||
|
||||
function youtube_parser(url){
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
return (match&&match[7].length==11)? match[7] : false;
|
||||
}
|
||||
// function youtube_parser(url){
|
||||
// var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
|
||||
// var match = url.match(regExp);
|
||||
// return (match&&match[7].length==11)? match[7] : false;
|
||||
// }
|
||||
|
||||
function get_thumbnail_image_url(item){
|
||||
let youtubeformat = item.links.split(";").find(s => s.startsWith('video|') && (s.includes('youtube.com') || s.includes('youtu.be')));
|
||||
let youtubeurl = youtubeformat && youtubeformat.split('|')[1];
|
||||
let ytid = youtubeurl && youtube_parser(youtubeurl);
|
||||
let thumbnail_image_url = ytid && `https://img.youtube.com/vi/${ytid}/mqdefault.jpg`
|
||||
return thumbnail_image_url
|
||||
}
|
||||
// function get_thumbnail_image_url(item){
|
||||
// let youtubeformat = item.links.split(";").find(s => s.startsWith('video|') && (s.includes('youtube.com') || s.includes('youtu.be')));
|
||||
// let youtubeurl = youtubeformat && youtubeformat.split('|')[1];
|
||||
// let ytid = youtubeurl && youtube_parser(youtubeurl);
|
||||
// let thumbnail_image_url = ytid && `https://img.youtube.com/vi/${ytid}/mqdefault.jpg`
|
||||
// return thumbnail_image_url
|
||||
// }
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
@ -23,79 +23,76 @@
|
|||
</script>
|
||||
|
||||
<div >
|
||||
<!-- Off-canvas menu for mobile, show/hide based on off-canvas menu state. -->
|
||||
{#if isNavDrawerOpen}
|
||||
<div class="relative z-40 md:hidden" role="dialog" aria-modal="true">
|
||||
<!--
|
||||
Off-canvas menu backdrop, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "transition-opacity ease-linear duration-300"
|
||||
From: "opacity-0"
|
||||
To: "opacity-100"
|
||||
Leaving: "transition-opacity ease-linear duration-300"
|
||||
From: "opacity-100"
|
||||
To: "opacity-0"
|
||||
-->
|
||||
<div class="fixed inset-0 bg-gray-600 bg-opacity-75"></div>
|
||||
|
||||
<div class="fixed inset-0 flex z-40">
|
||||
<!--
|
||||
Off-canvas menu, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "transition ease-in-out duration-300 transform"
|
||||
From: "-translate-x-full"
|
||||
To: "translate-x-0"
|
||||
Leaving: "transition ease-in-out duration-300 transform"
|
||||
From: "translate-x-0"
|
||||
To: "-translate-x-full"
|
||||
-->
|
||||
<div class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-lightSecondary2 text-lightSecondary1 dark:bg-darkSecondary2 dark:text-darkSecondary1">
|
||||
<!--
|
||||
Close button, show/hide based on off-canvas menu state.
|
||||
|
||||
Entering: "ease-in-out duration-300"
|
||||
From: "opacity-0"
|
||||
To: "opacity-100"
|
||||
Leaving: "ease-in-out duration-300"
|
||||
From: "opacity-100"
|
||||
To: "opacity-0"
|
||||
-->
|
||||
<div class="absolute top-0 right-0 -mr-12 pt-2">
|
||||
<button on:click={e => isNavDrawerOpen = false} type="button" class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
|
||||
<span class="sr-only">Close sidebar</span>
|
||||
<!-- Heroicon name: outline/x -->
|
||||
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex-shrink-0 flex items-center px-4">
|
||||
<a href="#/" class="">LearnAwesome</a>
|
||||
</div>
|
||||
<div class="mt-5 flex-1 h-0 overflow-y-auto">
|
||||
<nav class="px-2 space-y-1">
|
||||
<slot name="sidebar"></slot>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-shrink-0 w-14" aria-hidden="true">
|
||||
<!-- Dummy element to force sidebar to shrink to fit close icon -->
|
||||
<div class="md:pl-64 flex flex-col flex-1">
|
||||
<div class=" sticky top-0 z-10 flex-shrink-0 flex bg-lightPrimary text-lightPrimCont shadow">
|
||||
{#if isNavDrawerOpen == false}
|
||||
<button on:click={e => isNavDrawerOpen = true} type="button" class="px-4 border-r border-gray-200 text-lightPrimCont focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 md:hidden">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<Icon kind="menu"/>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if isNavDrawerOpen}
|
||||
<button on:click={e => isNavDrawerOpen = false} type="button" class="px-4 border-r border-gray-200 text-lightPrimCont focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 md:hidden">
|
||||
<span class="sr-only">Close sidebar</span>
|
||||
<Icon kind="close"/>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<div class="md:hidden py-3 flex flex-col items-center flex-shrink-0 px-4 tracking-wider font-bold text-lightPrimCont group">
|
||||
<a href="/" class="">LearnAwesome</a>
|
||||
<div class="w-1/5 mt-0.25 h-0.5 bg-white group-hover:w-full ease-in-out duration-300"></div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 flex justify-between">
|
||||
|
||||
{#if showNotificationBell || showProfileMenu}
|
||||
<div class="ml-4 flex items-center md:ml-6">
|
||||
{#if showNotificationBell}
|
||||
<button type="button" class="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
<span class="sr-only">View notifications</span>
|
||||
<Icon kind="bell"/>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if showProfileMenu}<MenuButton />{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div class="hidden md:flex md:w-64 md:flex-col md:fixed md:inset-y-0">
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex flex-col flex-grow pt-5 border-r overflow-y-auto">
|
||||
<div class="flex items-center flex-shrink-0 px-4 tracking-wider font-bold text-lightTertiary">
|
||||
<a href="/" class="">LearnAwesome</a>
|
||||
|
||||
<!-- content -->
|
||||
<main class="">
|
||||
<div class="py-6">
|
||||
<div class="max-w-none mx-auto px-4 sm:px-6 md:px-8">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<div class="mt-5 flex-1 flex flex-col bg-lightTertiary text-lightBg">
|
||||
<nav class="flex-1 pb-4 space-y-1">
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<!-- Off-canvas menu for mobile, show/hide based on off-canvas menu state. -->
|
||||
{#if isNavDrawerOpen}
|
||||
<div class="relative z-40 md:hidden" role="dialog" aria-modal="true">
|
||||
<div class="fixed inset-0 bg-lightSecondary bg-opacity-75 mt-12" on:click={e => isNavDrawerOpen = false}></div>
|
||||
|
||||
<div class="fixed inset-y-0 left-0 flex z-50 mt-12">
|
||||
<div class="relative flex-1 flex flex-col w-64 w-full pt-5 pb-4 bg-lightPrimary text-lightBg dark:bg-darkSecondary dark:text-darkBg">
|
||||
<!-- <div class="absolute top-0 right-0 -mr-12 pt-2"> -->
|
||||
|
||||
<!-- <button on:click={e => isNavDrawerOpen = false} type="button" class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
|
||||
<span class="sr-only">Close sidebar</span> -->
|
||||
<!-- Heroicon name: outline/x -->
|
||||
<!-- <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<!-- <div class="flex-shrink-0 flex items-center tracking-wider font-bold text-lightPrimCont">
|
||||
<a href="#/" class="">LearnAwesome</a>
|
||||
</div> -->
|
||||
<div class="ml-6 flex-1 h-0 overflow-y-auto">
|
||||
<nav class="px-4 space-y-1" on:click={e => isNavDrawerOpen = false}>
|
||||
<slot name="nav"></slot>
|
||||
{#if window.location.href.startsWith('http://127.0.0.1')}
|
||||
<button class="" on:click={themeRandomize}>Randomize</button>
|
||||
|
@ -103,36 +100,26 @@
|
|||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:pl-64 flex flex-col flex-1">
|
||||
<div class="sticky top-0 z-10 flex-shrink-0 flex bg-cyan-900 text-white shadow">
|
||||
<button on:click={e => isNavDrawerOpen = true} type="button" class="px-4 border-r border-gray-200 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 md:hidden">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<Icon kind="menu"/>
|
||||
</button>
|
||||
<div class="flex-1 flex justify-between">
|
||||
|
||||
{#if showNotificationBell || showProfileMenu}
|
||||
<div class="ml-4 flex items-center md:ml-6">
|
||||
{#if showNotificationBell}
|
||||
<button type="button" class="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
<span class="sr-only">View notifications</span>
|
||||
<Icon kind="bell"/>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
{#if showProfileMenu}<MenuButton />{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="">
|
||||
<div class="py-6">
|
||||
<div class="max-w-none mx-auto px-4 sm:px-6 md:px-8">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- <div class="flex-shrink-0 w-14" aria-hidden="true"> -->
|
||||
<!-- Dummy element to force sidebar to shrink to fit close icon -->
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div class="hidden md:flex md:w-64 md:flex-col md:fixed md:inset-y-0">
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex flex-col flex-grow pt-5 border-r overflow-y-auto">
|
||||
<div class="flex items-center flex-shrink-0 px-4 tracking-wider font-bold text-lightTertiary">
|
||||
<a href="/" class="">LearnAwesome</a>
|
||||
</div>
|
||||
<div class="mt-5 flex-1 flex flex-col bg-lightTertiary text-lightBg">
|
||||
<nav class="flex-1 pb-4 space-y-1">
|
||||
<slot name="nav"></slot>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -13,6 +13,11 @@
|
|||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h7" />
|
||||
</svg>
|
||||
{:else if kind === "close"}
|
||||
<!-- Heroicon name: outline/x -->
|
||||
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
{:else if kind === "bell"}
|
||||
<!-- Heroicon name: outline/bell -->
|
||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
|
@ -24,12 +29,12 @@
|
|||
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{:else if kind === "dots"}
|
||||
<!-- Heroicon name: solid/dots-vertical -->
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
|
||||
</svg>
|
||||
<!-- Heroicon name: solid/dots-vertical -->
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
|
||||
</svg>
|
||||
{:else if kind === "link"}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
{/if}
|
|
@ -9,35 +9,26 @@
|
|||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// lightPrimaryBg: 'rgb(248 250 252)', //bg-slate-50
|
||||
// lightPrimaryText: 'rgb(15 23 42)', //bg-slate-900
|
||||
// lightSecondary1: 'rgb(250 245 255)', //bg-purple-50
|
||||
// lightSecondary2: 'rgb(88 28 135)', //bg-purple-900
|
||||
// lightButton1: 'rgb(240 253 250)', //bg-teal-50
|
||||
// lightButton2: 'rgb(19 78 74)', //bg-teal-900
|
||||
|
||||
// darkPrimaryBg: 'rgb(15 23 42)', //bg-slate-900
|
||||
// darkPrimaryText: 'rgb(248 250 252)', //bg-slate-50
|
||||
// darkSecondary1: 'rgb(88 28 135)', //bg-purple-900
|
||||
// darkSecondary2: 'rgb(250 245 255)', //bg-purple-50
|
||||
// darkButton1: 'rgb(19 78 74)', //bg-teal-900
|
||||
// darkButton2: 'rgb(240 253 250)', //bg-teal-50
|
||||
// darkSecondaryBg: 'rgb(30 41 59)', //bg-slate-800
|
||||
|
||||
lightPrimary: 'rgb(30 64 175)', //blue-800
|
||||
lightSecondary: 'rgb(75 85 99)', //gray-600
|
||||
lightTertiary: 'rgb(168 85 247)', //purple-500
|
||||
lightBg: '#fafafa', //zinc-50
|
||||
lightPrimCont: '#dbeafe', // blue-200
|
||||
lightButtonBg: 'rgb(20 83 45)', //green-900
|
||||
light: '#ffffff', //white
|
||||
|
||||
dark: '#0F172A', //slate-900
|
||||
darkPrimary: 'rgb(147 197 253)', //blue-300
|
||||
darkSecondary: 'rgb(203 213 225)', //slate-300
|
||||
darkTertiary: 'rgb(216 180 254)', //purple-300
|
||||
darkBg: 'rgb(23 23 23)', //nutral-900
|
||||
darkPrimCont: 'rgb(3 105 161)', //sky-700
|
||||
darkButtonBg: 'rgb(34 197 94)'//green-500
|
||||
}
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Gentium Plus', 'sans'],
|
||||
serif: ['Libre Franklin','serif']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,8 +45,12 @@
|
|||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Franklin:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- fonts Gentium Plus -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Gentium+Plus:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body style="font-family: 'Libre Franklin', sans-serif;" class="max-w-none mx-auto h-full bg-lightBg dark:bg-darkBg text-lightPrimary dark:text-darkPrimary">
|
||||
<body class="max-w-none mx-auto h-full bg-light dark:bg-dark text-lightPrimary dark:text-darkPrimary font-serif">
|
||||
<div class="h-full" id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Ładowanie…
Reference in New Issue