Skip to content

Commit

Permalink
Merge pull request #279 from php-school/home-page-copy
Browse files Browse the repository at this point in the history
Update some copy, reimplement slack invite
  • Loading branch information
AydinHassan authored Mar 10, 2024
2 parents e8d0d22 + e555a93 commit edebf67
Show file tree
Hide file tree
Showing 25 changed files with 1,108 additions and 749 deletions.
2 changes: 1 addition & 1 deletion .docker/files/php-school-fpm/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:8.1-fpm AS prod
FROM php:8.3-fpm AS prod

RUN apt-get -qq update && apt-get install -qqy git zlib1g-dev libzip-dev \
&& rm -rf /var/lib/apt/lists/* \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [8.1, 8.2]
php: [8.2, 8.3]

name: PHP ${{ matrix.php }}
steps:
Expand Down
19 changes: 16 additions & 3 deletions app/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use PhpSchool\Website\Action\Online\ComposerPackageAdd;
use PhpSchool\Website\Action\Online\RunExercise;
use PhpSchool\Website\Action\Online\VerifyExercise;
use PhpSchool\Website\Action\SlackInvite;
use PhpSchool\Website\Action\StudentLogin;
use PhpSchool\Website\Action\SubmitWorkshop;
use PhpSchool\Website\Action\TrackDownloads;
Expand Down Expand Up @@ -232,14 +233,21 @@
SubmitWorkshop::class => \DI\factory(function (ContainerInterface $c): SubmitWorkshop {
return new SubmitWorkshop(
$c->get(FormHandlerFactory::class)->create(
new SubmitWorkshopInputFilter(new Client, $c->get(WorkshopRepository::class))
new SubmitWorkshopInputFilter(new Client(), $c->get(WorkshopRepository::class))
),
new WorkshopCreator(new WorkshopComposerJsonInputFilter, $c->get(WorkshopRepository::class)),
new WorkshopCreator(new WorkshopComposerJsonInputFilter(), $c->get(WorkshopRepository::class)),
$c->get(EmailNotifier::class),
$c->get(LoggerInterface::class)
);
}),

SlackInvite::class => function (ContainerInterface $c): SlackInvite {
return new SlackInvite(
$c->get('guzzle'),
$c->get('config')['slackInviteApiToken']
);
},

Github::class => function (ContainerInterface $c): Github {
return new Github([
'clientId' => $c->get('config')['github']['clientId'],
Expand Down Expand Up @@ -320,6 +328,10 @@
);
},

'guzzle' => function (ContainerInterface $c): \GuzzleHttp\Client {
return new \GuzzleHttp\Client();
},

'guzzle.packagist' => function (ContainerInterface $c) {
return new \GuzzleHttp\Client(['headers' => ['User-Agent' => 'PHP School: [email protected]']]);
},
Expand Down Expand Up @@ -618,7 +630,8 @@ public function parse($markdown): string
'clientSecret' => $_ENV['GITHUB_CLIENT_SECRET'],
],

'jwtSecret' => $_ENV['JWT_SECRET']
'jwtSecret' => $_ENV['JWT_SECRET'],
'slackInviteApiToken' => $_ENV['SLACK_INVITE_API_TOKEN'],
],

//slim settings
Expand Down
2 changes: 1 addition & 1 deletion assets/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const docRoutes = [].concat(

const routes = [
{ path: "/", component: Home, meta: { layout: MainLayout } },
{ path: "/online", component: Dashboard, meta: { layout: CompactLayout } },
{ path: "/online/:workshop?", component: Dashboard, meta: { layout: CompactLayout } },
{
path: "/online/editor/:workshop/:exercise",
component: ExerciseEditor,
Expand Down
19 changes: 12 additions & 7 deletions assets/components/Online/ExerciseVerify.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ const enableRateLimitError = () => {
};
const runSolution = async () => {
currentAction.value = "run";
if (loadingRun.value) {
return;
}
Expand Down Expand Up @@ -81,8 +79,6 @@ const runSolution = async () => {
};
const verifySolution = () => {
currentAction.value = "verify";
if (loadingVerify.value) {
return;
}
Expand Down Expand Up @@ -183,16 +179,25 @@ const verifySolution = () => {
>
<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">
<button
@click.stop="
currentAction = 'run';
runSolution();
"
class="flex h-[48px] w-full flex-1 items-center justify-start rounded px-4 text-sm text-white"
: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'"
@click.stop="
currentAction = 'verify';
verifySolution();
"
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>
Expand Down
17 changes: 16 additions & 1 deletion assets/components/Online/WorkshopExerciseSelectionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,41 @@
import { CheckCircleIcon, CommandLineIcon } from "@heroicons/vue/24/solid";
import { ArrowRightCircleIcon } from "@heroicons/vue/24/outline";
import ExerciseEntry from "./ExerciseEntry.vue";
import { ref } from "vue";
import { ref, watch } from "vue";
import Alert from "./SiteAlert.vue";
import { useStudentStore } from "../../stores/student";
const studentStore = useStudentStore();
import { useWorkshopStore } from "../../stores/workshops";
import { useRoute } from "vue-router";
const workshopStore = useWorkshopStore();
const selectedWorkshop = ref(null);
const showNotLoggedInError = ref(false);
const route = useRoute();
const notLoggedIn = () => {
showNotLoggedInError.value = true;
};
const selectWorkshop = (workshopCode) => {
selectedWorkshop.value = workshopStore.workshops.find((workshop) => workshop.code === workshopCode);
history.pushState({}, null, "/online/" + workshopCode);
};
watch(
() => route.params,
(toParams) => {
if (toParams.workshop) {
selectedWorkshop.value = workshopStore.workshops.find((workshop) => workshop.code === toParams.workshop);
}
},
{ immediate: true },
);
</script>

<template>
Expand Down
3 changes: 2 additions & 1 deletion assets/components/Website/Docs/BundledCheck.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ defineProps({
compatible: {
type: Array,
validator(value) {
return ["CLI, CGI"].includes(value);
return value.every((v) => ["CLI", "CGI"].includes(v));
},
default: () => ["CLI", "CGI"],
},
registered: {
type: Boolean,
Expand Down
30 changes: 4 additions & 26 deletions assets/components/Website/Docs/DocTitle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup>
import { computed } from "vue";
import { PencilSquareIcon } from "@heroicons/vue/24/outline";
const props = defineProps({
id: {
Expand All @@ -24,38 +25,15 @@ const slug = computed(() => {
<template>
<h2 :id="id" class="relative mb-4 flex items-center border-b border-gray-600 pb-1 pt-2 font-mono text-2xl">
<span class="text-[#e91e63]">{{ title }}</span>
<a class="ml-2 inline-block !text-gray-300 hover:!text-gray-200 hover:underline" :href="'#' + slug">#</a>
<a class="ml-2 inline-block !text-gray-300 hover:text-gray-200 hover:underline" :href="'#' + slug">#</a>
<a
v-if="file"
title="Edit this page on GitHub!"
target="_blank"
class="ml-2 inline-block fill-current !text-gray-300 hover:!text-gray-200"
class="ml-2 inline-block fill-current !text-gray-300 hover:!text-[#e91e63]"
:href="'https://www.github.com/php-school/phpschool.io/tree/master/assets/components/Website/Docs/Sections/' + file"
>
<svg
class="h-4 w-4"
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
width="612px"
height="612px"
viewBox="0 0 612 612"
style="enable-background: new 0 0 612 612"
xml:space="preserve"
>
<g>
<g id="New_x5F_Post">
<g>
<path
d="M545.062,286.875c-15.854,0-28.688,12.852-28.688,28.688v239.062h-459v-459h239.062c15.854,0,28.688-12.852,28.688-28.688S312.292,38.25,296.438,38.25H38.25C17.136,38.25,0,55.367,0,76.5v497.25C0,594.883,17.136,612,38.25,612H535.5c21.114,0,38.25-17.117,38.25-38.25V315.562C573.75,299.727,560.917,286.875,545.062,286.875z M605.325,88.95L523.03,6.655C518.556,2.18,512.684,0,506.812,0s-11.743,2.18-16.218,6.675l-318.47,318.45v114.75h114.75l318.45-318.45c4.494-4.495,6.675-10.366,6.675-16.237C612,99.297,609.819,93.445,605.325,88.95z M267.75,382.5H229.5v-38.25L506.812,66.938l38.25,38.25L267.75,382.5z"
/>
</g>
</g>
</g>
</svg>
<PencilSquareIcon class="h-5 w-5"></PencilSquareIcon>
</a>
<a href="#app" class="absolute right-0 text-xs hover:underline">^ TOP</a>
</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import ContentHeader from "../../ContentHeader.vue";

<ContentHeader id="tutorial-sections">Tutorial Sections</ContentHeader>

<h3>
<h3 class="mb-2">
<router-link to="/docs/tutorial/creating-your-own-workshop">1. Creating your own workshop</router-link>
</h3>
<p>Learn how to create and setup your very own workshop.</p>
<h3>
<h3 class="mb-2">
<router-link to="/docs/tutorial/modify-theme">2. Modifying the theme of your workshop</router-link>
</h3>
<p>Customise the look and feel of your workshop, personalise to your brand or subject.</p>
<h3>
<h3 class="mb-2">
<router-link to="/docs/tutorial/creating-an-exercise">3. Creating an exercise</router-link>
</h3>
<p>Create the first exercise for your workshop.</p>
Expand Down
10 changes: 5 additions & 5 deletions assets/components/Website/Docs/contents.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const docs = [
path: "",
title: "Documentation Home",
component: DocHome,
file: "Index.vue",
file: "DocHome.vue",
},
],
},
Expand All @@ -41,7 +41,7 @@ const docs = [
path: "",
title: "Workshop Tutorial",
component: TutorialHome,
file: "Tutorial/Index.vue",
file: "Tutorial/TutorialHome.vue",
},
{
path: "creating-your-own-workshop",
Expand Down Expand Up @@ -71,7 +71,7 @@ const docs = [
path: "",
title: "Reference Documentation",
component: ReferenceHome,
file: "Reference/Index.vue",
file: "Reference/ReferenceHome.vue",
},
{
path: "container",
Expand Down Expand Up @@ -101,7 +101,7 @@ const docs = [
path: "results",
title: "Results & Renderers",
component: Results,
file: "Reference/Results.vue",
file: "Reference/CheckResults.vue",
},
{
path: "exercise-checks",
Expand Down Expand Up @@ -137,7 +137,7 @@ const docs = [
path: "events",
title: "Events",
component: Events,
file: "Reference/Events.vue",
file: "Reference/ExerciseEvents.vue",
},
{
path: "creating-listener-checks",
Expand Down
84 changes: 84 additions & 0 deletions assets/components/Website/JoinSlack.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<script setup>
import PrimaryButton from "./PrimaryButton.vue";
import { ChatBubbleLeftRightIcon } from "@heroicons/vue/24/solid";
import Modal from "../Online/ModalDialog.vue";
import { useStudentStore } from "../../stores/student";
import { ref } from "vue";
const studentStore = useStudentStore();
const inviteSent = ref(false);
const inviteError = ref(null);
const email = ref(studentStore.student ? studentStore.student.email : "");
const { open } = defineProps({
open: Boolean,
});
const emit = defineEmits(["close"]);
const sendInvite = async () => {
const response = await fetch("/api/slack-invite", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
email: email.value,
}),
});
inviteSent.value = true;
if (!response.ok) {
const data = await response.json();
inviteError.value = data.error;
}
};
</script>

<template>
<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 :scroll-content="true" size="md" max-height="max-h-[calc(5/6*100%)]" v-if="open" @close="emit('close')">
<template #header>
<div class="flex items-center">
<ChatBubbleLeftRightIcon 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">Community Slack</h3>
</div>
</template>
<template #body>
<p class="text-white">
You can find our community slack
<a target="_blank" class="text-[#e91e63] hover:underline" href="https://phpschool-team.slack.com/archives/C0CGDLNFL">here</a>
. If you don't have an account, use the form below with your e-mail to get an invite.
</p>

<div v-if="!inviteSent" class="relative flex w-full items-center pb-2 pt-6">
<input
type="email"
placeholder="Type Something..."
v-model="email"
class="w-full rounded-2xl border-0 p-5 font-work-sans text-base font-bold text-gray-900 focus:border-pink-500 focus:outline-none focus:ring focus:ring-pink-500"
/>
<PrimaryButton
@click.stop="sendInvite"
class="absolute right-0 m-0 flex h-[52px] items-center justify-center rounded-xl bg-gradient-to-r from-pink-600 to-purple-500 px-2 text-sm normal-case text-white shadow-none transition-all duration-300 ease-in hover:bg-[#aa1145] hover:opacity-90"
>
<span>Request Invite</span>
</PrimaryButton>
</div>
<p v-if="inviteSent && inviteError === null" class="mt-4 w-full text-center text-base text-[#e91e63]"><i>Invite was sent, please check your e-mails.</i></p>
<p v-if="inviteSent && inviteError" class="mt-4 w-full text-center text-base text-red-600">{{ inviteError }}</p>
</template>
</Modal>
</Transition>
</Teleport>
</template>
4 changes: 2 additions & 2 deletions assets/components/Website/MainLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import SiteFooter from "./SiteFooter.vue";

<template>
<div class="flex min-h-screen flex-col">
<site-nav></site-nav>
<SiteNav></SiteNav>
<div class="flex-1 bg-gray-900">
<slot></slot>
</div>
<site-footer></site-footer>
<SiteFooter></SiteFooter>
</div>
</template>
Loading

0 comments on commit edebf67

Please sign in to comment.