Skip to content

Commit

Permalink
Merge pull request #276 from php-school/mobile-improvements-3
Browse files Browse the repository at this point in the history
Mobile improvements 3
  • Loading branch information
AydinHassan authored Feb 5, 2024
2 parents 541d41d + a612273 commit 750db78
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 94 deletions.
2 changes: 1 addition & 1 deletion assets/components/Online/ComposerPackages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const removeDependency = (packageName) => {
:disabled="newDependency === ''"
@click.stop="addDependency"
type="button"
class="inline-flex h-9 w-16 items-center justify-center rounded-full border border-transparent bg-pink-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-pink-700 focus:outline-none focus:ring focus:ring-pink-800 disabled:opacity-70 disabled:hover:bg-pink-600 sm:ml-3 sm:text-sm"
class="ml-3 inline-flex h-9 w-16 items-center justify-center rounded-full border border-transparent bg-pink-600 px-4 py-2 text-base text-sm font-medium text-white shadow-sm hover:bg-pink-700 focus:outline-none focus:ring focus:ring-pink-800 disabled:opacity-70 disabled:hover:bg-pink-600"
>
<ArrowPathIcon v-cloak v-show="loadingComposerAdd" class="h-4 w-4 animate-spin" />
<span v-if="!loadingComposerAdd">Add</span>
Expand Down
8 changes: 3 additions & 5 deletions assets/components/Online/EditorBreadcrumbs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ const exerciseCompleted = computed(() => {
</div>
</li>
<li>
<div class="flex items-center">
<span v-if="exerciseCompleted" title="You've already completed this exercise!">
<TrophyIcon class="h-6 w-6 text-yellow-400" />
</span>
</div>
<span class="ml-1 flex items-center md:ml-0" v-if="exerciseCompleted" title="You've already completed this exercise!">
<TrophyIcon class="h-4 w-4 text-yellow-400 md:h-6 md:w-6" />
</span>
</li>
</ol>
</nav>
Expand Down
199 changes: 127 additions & 72 deletions assets/components/Online/ExerciseVerify.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import Modal from "./ModalDialog.vue";
import { ArrowPathIcon, CommandLineIcon, SparklesIcon } from "@heroicons/vue/24/solid";
import toFilePath from "./Utils/toFilePath";
import RunResult from "./RunResult.vue";
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from "@headlessui/vue";
import { Menu, MenuButton, MenuItem, MenuItems, Tab, TabGroup, TabList, TabPanel, TabPanels } from "@headlessui/vue";
import Alert from "./SiteAlert.vue";
import { ref } from "vue";
import { ChevronDownIcon } from "@heroicons/vue/20/solid";
const emit = defineEmits(["verify-loading", "verify-success", "verify-fail", "run-loaded"]);
const props = defineProps({
Expand All @@ -20,6 +21,7 @@ const programRunResult = ref(null);
const openRunModal = ref(false);
const loadingVerify = ref(false);
const showRateLimitError = ref(false);
const currentAction = ref("verify");
const flattenFiles = (nodes, files = {}) => {
nodes.forEach((node) => {
Expand All @@ -37,6 +39,8 @@ const enableRateLimitError = () => {
};
const runSolution = async () => {
currentAction.value = "run";
if (loadingRun.value) {
return;
}
Expand Down Expand Up @@ -77,6 +81,8 @@ const runSolution = async () => {
};
const verifySolution = () => {
currentAction.value = "verify";
if (loadingVerify.value) {
return;
}
Expand Down Expand Up @@ -128,7 +134,7 @@ const verifySolution = () => {
<template>
<alert type="error" @close="showRateLimitError = false" :show="showRateLimitError" :timeout="4000" message="Too many requests. Please try again in a few minutes."></alert>
<div class="flex flex-1 items-center gap-y-2">
<div class="flex h-[48px] flex-1 items-center gap-y-2">
<button
id="run"
class="mr-2 mt-0 hidden h-[48px] w-44 items-center justify-center rounded border-2 border-solid border-[#E91E63] px-4 text-sm text-white hover:bg-[#E91E63] md:flex"
Expand All @@ -139,76 +145,125 @@ const verifySolution = () => {
<span v-if="!loadingRun">Run</span>
<CommandLineIcon v-if="!loadingRun" v-cloak class="ml-2 h-5 w-5" />
</button>
<button
id="verify"
class="mr-0 mt-0 flex h-[48px] w-full items-center justify-center rounded bg-gradient-to-r from-pink-600 to-purple-500 px-4 text-sm text-white transition-all duration-300 ease-in hover:bg-[#aa1145] md:mr-2 md:w-44"
@click="verifySolution"
:disabled="loadingVerify"
>
<ArrowPathIcon v-cloak v-show="loadingVerify" class="h-4 w-4 animate-spin" />
<span v-if="!loadingVerify">Verify</span>
<SparklesIcon v-if="!loadingVerify" v-cloak class="ml-2 h-5 w-5" />
</button>
</div>
<Transition
enter-active-class="transition-opacity duration-100 ease-in"
leave-active-class="transition-opacity duration-200 ease-in"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<Modal id="run-modal" :scroll-content="true" size="3xl" max-height="max-h-[calc(5/6*100%)]" v-if="openRunModal" @close="openRunModal = false">
<template #header>
<div class="flex items-center">
<CommandLineIcon class="mr-2 h-6 w-6 text-pink-500" />
<h3 class="mt-0 pt-0 font-mono text-base font-semibold text-white lg:text-xl">Program output</h3>
</div>
</template>
<template #body>
<div class="">
<template v-if="programRunResult && programRunResult.success === false">
<h2 class="mb-2 pt-0 font-mono text-lg text-[#E91E63]">Your program could not be executed, there was a syntax error</h2>
<pre class="mb-4 whitespace-pre-wrap rounded-none border-none p-0"><code class="language-shell hljs shell block rounded-lg p-4 text-sm">{{programRunResult.failure.reason}}</code></pre>
</template>
<TabGroup v-else-if="programRunResult && programRunResult.runs.length > 1">
<TabList className="flex justify-center border-b border-solid border-gray-600">
<Tab as="template" v-slot="{ selected }" v-for="(run, i) in programRunResult.runs" :key="i">
<button
:class="{
'border-b-2 border-pink-500 px-4 py-3 text-pink-400': selected,
' px-4 py-3 text-white': !selected,
}"
>
Run #{{ i + 1 }}
</button>
</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="(run, i) in programRunResult.runs" :key="i">
<run-result :exercise="currentExercise.exercise" :run="run" class="mt-6" />
</TabPanel>
</TabPanels>
</TabGroup>
<run-result v-else :exercise="currentExercise.exercise" :run="programRunResult.runs[0]" />
</div>
</template>
<template #footer>
<div class="flex justify-end">
<button
type="button"
v-show="programRunResult.success === true"
class="inline-flex w-full items-center justify-center rounded-full border border-transparent bg-pink-600 px-8 py-2 text-base font-medium text-white shadow-sm hover:bg-pink-700 focus:outline-none focus:ring focus:ring-pink-800 sm:ml-3 sm:w-auto sm:text-sm"
@click="runSolution"
>
<ArrowPathIcon :class="{ 'animate-spin': loadingRun }" class="-ml-1 mr-2 h-4 w-4" />
Run again
</button>
<div class="flex h-[48px] w-full justify-between rounded bg-gradient-to-r from-pink-600 to-purple-500 px-3 md:w-44 md:justify-center">
<button class="mr-0 mt-0 flex h-[48px] w-full items-center text-sm text-white transition-all duration-300 ease-in">
<span v-if="currentAction === 'verify'" class="flex flex-1 items-center md:justify-center" @click="verifySolution">
<ArrowPathIcon v-cloak v-show="loadingVerify" class="hidden h-4 w-4 animate-spin md:flex" />
<span :class="{ 'md:hidden': loadingVerify }">Verify</span>
<SparklesIcon :class="{ 'md:hidden': loadingVerify }" v-cloak class="ml-2 h-5 w-5" />
</span>
<span v-if="currentAction === 'run'" class="flex flex-1 items-center md:justify-center" @click="runSolution">
<ArrowPathIcon v-cloak v-show="loadingRun" class="hidden h-4 w-4 animate-spin md:flex" />
<span>Run</span>
<CommandLineIcon v-cloak class="ml-2 h-5 w-5" />
</span>
</button>
<Menu as="div" class="relative text-xs uppercase text-white" v-slot="{ open }">
<div class="group">
<MenuButton class="h-[48px]" :disabled="loadingVerify || loadingRun">
<ChevronDownIcon
v-if="!loadingRun && !loadingVerify"
:class="open ? '' : 'rotate-180'"
class="ml-2 flex h-5 w-5 transition duration-200 duration-300 focus:outline-none md:hidden"
aria-hidden="true"
/>
<ArrowPathIcon v-cloak v-show="loadingVerify || loadingRun" class="ml-2 flex h-4 w-4 animate-spin md:hidden" />
</MenuButton>
</div>
</template>
</Modal>
</Transition>
<transition
enter-active-class="transition ease-out duration-100"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95"
>
<MenuItems class="absolute -right-3 -top-2 z-40 w-[168px] origin-top-right -translate-y-full rounded-md bg-gradient-to-r from-pink-600 to-purple-500 px-3 text-left">
<MenuItem v-if="currentAction === 'verify'">
<button class="flex h-[48px] w-full flex-1 items-center justify-start rounded px-4 text-sm text-white" @click.stop="runSolution" :disabled="loadingRun">
<span>Run</span>
<CommandLineIcon class="ml-2 h-5 w-5" />
</button>
</MenuItem>
<MenuItem v-if="currentAction === 'run'">
<button
v-if="currentAction === 'run'"
class="flex h-[48px] w-full flex-1 items-center justify-start rounded px-4 text-sm text-white"
@click.stop="verifySolution"
:disabled="loadingVerify"
>
<span>Verify</span>
<SparklesIcon class="ml-2 h-5 w-5" />
</button>
</MenuItem>
</MenuItems>
</transition>
</Menu>
</div>
</div>
<Teleport to="body">
<Transition
enter-active-class="transition-opacity duration-100 ease-in"
leave-active-class="transition-opacity duration-200 ease-in"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<Modal id="run-modal" :scroll-content="true" size="3xl" max-height="max-h-[calc(5/6*100%)]" v-if="openRunModal" @close="openRunModal = false">
<template #header>
<div class="flex items-center">
<CommandLineIcon class="mr-2 h-6 w-6 text-pink-500" />
<h3 class="mt-0 pt-0 font-mono text-base font-semibold text-white lg:text-xl">Program output</h3>
</div>
</template>
<template #body>
<div class="">
<template v-if="programRunResult && programRunResult.success === false">
<h2 class="mb-2 pt-0 font-mono text-lg text-[#E91E63]">Your program could not be executed, there was a syntax error</h2>
<pre class="mb-4 whitespace-pre-wrap rounded-none border-none p-0"><code class="language-shell hljs shell block rounded-lg p-4 text-sm">{{programRunResult.failure.reason}}</code></pre>
</template>
<TabGroup v-else-if="programRunResult && programRunResult.runs.length > 1">
<TabList className="flex justify-center border-b border-solid border-gray-600">
<Tab as="template" v-slot="{ selected }" v-for="(run, i) in programRunResult.runs" :key="i">
<button
:class="{
'border-b-2 border-pink-500 px-4 py-3 text-pink-400': selected,
' px-4 py-3 text-white': !selected,
}"
>
Run #{{ i + 1 }}
</button>
</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="(run, i) in programRunResult.runs" :key="i">
<run-result :exercise="currentExercise.exercise" :run="run" class="mt-6" />
</TabPanel>
</TabPanels>
</TabGroup>
<run-result v-else :exercise="currentExercise.exercise" :run="programRunResult.runs[0]" />
</div>
</template>
<template #footer>
<div class="flex justify-end">
<button
type="button"
v-show="programRunResult.success === true"
class="inline-flex w-full items-center justify-center rounded-full border border-transparent bg-pink-600 px-8 py-2 text-base font-medium text-white shadow-sm hover:bg-pink-700 focus:outline-none focus:ring focus:ring-pink-800 sm:ml-3 sm:w-auto sm:text-sm"
@click="runSolution"
>
<ArrowPathIcon :class="{ 'animate-spin': loadingRun }" class="-ml-1 mr-2 h-4 w-4" />
Run again
</button>
</div>
</template>
</Modal>
</Transition>
</Teleport>
</template>
12 changes: 6 additions & 6 deletions assets/components/Online/PageExerciseEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,12 @@ const deleteFileOrFolder = async (file) => {
<TransitionRoot :show="openResults">
<TransitionChild
as="template"
enter="transform transition ease-in-out duration-500 sm:duration-700"
enter-from="-translate-y-full"
enter-to="translate-y-0"
enter="transform transition ease-in-out duration-300 sm:duration-700"
enter-from="-translate-y-full md:translate-y-0 md:translate-x-full"
enter-to="translate-y-0 md:translate-x-0"
leave="transform transition ease-in-out duration-300 sm:duration-700"
leave-from="translate-y-0"
leave-to="-translate-y-full"
leave-from="translate-y-0 md:translate-x-0"
leave-to="-translate-y-full md:translate-y-0 md:translate-x-full"
>
<div id="results-col" class="absolute right-0 z-10 flex h-full w-full flex-col overflow-y-scroll border-t border-solid border-gray-600 bg-gray-900 md:mt-0 md:w-3/12 md:border-l">
<div class="flex items-center justify-between border-b border-solid border-gray-600 py-4 pl-4 pr-4">
Expand Down Expand Up @@ -440,7 +440,7 @@ const deleteFileOrFolder = async (file) => {
<!-- start footer -->
<div class="flex flex-wrap items-center justify-between gap-y-3 border-t border-solid border-gray-600 p-2 md:mb-0 md:gap-y-0">
<editor-breadcrumbs :current-exercise="currentExercise" class="order-3 md:order-1"></editor-breadcrumbs>
<progress-bar class="order-2"></progress-bar>
<progress-bar></progress-bar>
<div class="order-1 flex w-full items-start justify-center gap-x-2 md:order-3 md:w-auto md:gap-x-0">
<button
ref="openFileBrowserButton"
Expand Down
9 changes: 6 additions & 3 deletions assets/components/Online/ProgressBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ const percentComplete = computed(() => {
</script>

<template>
<div class="relative mt-0 flex h-5 w-full items-center justify-center rounded-full bg-gray-200 bg-gray-700 lg:w-1/6">
<div class="absolute left-0 h-5 rounded-full bg-pink-500" :style="{ width: percentComplete + '%' }"></div>
<p class="absolute mx-auto ml-2 inline-flex items-center text-xs font-bold text-white">{{ studentStore.totalCompleted() }} / {{ workshopStore.totalExercises }} completed</p>
<div class="order-2 flex w-full items-center lg:w-1/6">
<div class="relative mt-0 flex h-2 flex-1 items-center justify-center rounded-full bg-gray-200 bg-gray-700 md:h-5">
<div class="absolute left-0 h-2 rounded-full bg-pink-500 md:h-5" :style="{ width: percentComplete + '%' }"></div>
<p class="absolute mx-auto ml-2 hidden items-center font-mono text-xs font-bold text-white md:inline-flex">{{ studentStore.totalCompleted() }}/{{ workshopStore.totalExercises }} Completed</p>
</div>
<p class="mx-auto ml-2 mr-2 items-center font-mono text-xs text-white md:hidden">{{ studentStore.totalCompleted() }}/{{ workshopStore.totalExercises }} Completed</p>
</div>
</template>
14 changes: 7 additions & 7 deletions assets/components/Online/SiteAlert.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ watch(
>
<div v-cloak v-show="show" class="absolute left-0 top-4 z-[51] flex w-full justify-center">
<div
class="mx-auto rounded-lg bg-gradient-to-r px-3 py-3 shadow-lg sm:px-6 lg:px-8"
class="mx-2 rounded-lg bg-gradient-to-r px-3 py-3 shadow-lg sm:px-6 md:mx-0 lg:px-8"
:class="{
'from-red-600 to-pink-700': type === 'error',
'from-pink-500 to-purple-500': type === 'success',
}"
>
<div class="flex flex-wrap items-center justify-center">
<div class="flex items-center">
<ExclamationTriangleIcon v-if="type === 'error'" class="h-6 w-6 text-white" />
<CheckIcon v-if="type === 'success'" class="h-6 w-6 text-white" />
<p class="ml-3 truncate font-medium text-white">
<span class="">{{ message }}</span>
<ExclamationTriangleIcon v-if="type === 'error'" class="h-5 w-5 text-white md:h-6 md:w-6" />
<CheckIcon v-if="type === 'success'" class="h-5 w-5 text-white md:h-6 md:w-6" />
<p class="ml-3 font-medium text-white">
<span class="text-sm md:text-base">{{ message }}</span>
</p>
</div>
<div class="order-2 flex-shrink-0 sm:order-3 sm:ml-3">
<button @click="$emit('close')" type="button" class="-mr-1 flex rounded-md p-2 hover:bg-pink-600 focus:outline-none focus:ring-2 focus:ring-white sm:-mr-2">
<button @click="$emit('close')" type="button" class="-mr-1 flex rounded-md p-1 hover:bg-pink-600 focus:outline-none focus:ring-2 focus:ring-white sm:-mr-2 md:p-2">
<span class="sr-only">Dismiss</span>
<XMarkIcon class="h-6 w-6 text-white" />
<XMarkIcon class="h-5 w-5 text-white md:h-6 md:w-6" />
</button>
</div>
</div>
Expand Down

0 comments on commit 750db78

Please sign in to comment.