Skip to content

Commit fbfcbe5

Browse files
authored
feat: onboarding (#2)
* wip * onboarding * better onboarding
1 parent 6169424 commit fbfcbe5

23 files changed

+10415
-13693
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# StudyHQ
22

3-
AI powered revision, exam generator and grader.
3+
AI powered revision, exam generator and grader.
44

55
https://studyhq.app
66

@@ -12,7 +12,6 @@ https://studyhq.app
1212
- Receive useful feedback
1313
- Retake exams to practice
1414

15-
1615
## Coming soon
1716

1817
- More customizable exams
@@ -21,7 +20,7 @@ https://studyhq.app
2120

2221
## TODO
2322

24-
- Figure out how to price this!
23+
- Figure out how to price this!
2524
- Allow bring your own API key
2625

2726
# Screenshots

components/NewButtons.vue

+16-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ const emits = defineEmits<{
77
(e: "newThread"): void;
88
(e: "newExam"): void;
99
}>();
10+
11+
const { guestMode, setShowSignUpModal } = useAuth();
12+
13+
function maybeEmit(event: "newThread" | "newExam") {
14+
if (guestMode.value) {
15+
setShowSignUpModal(true);
16+
} else {
17+
if (event === "newExam") {
18+
emits("newExam");
19+
} else if (event === "newThread") {
20+
emits("newThread");
21+
}
22+
}
23+
}
1024
</script>
1125

1226
<template>
@@ -16,15 +30,15 @@ const emits = defineEmits<{
1630
size="xs"
1731
:disabled="disabled"
1832
:loading="disabled"
19-
@click="emits('newThread')"
33+
@click="maybeEmit('newThread')"
2034
>
2135
New Chat</UButton
2236
>
2337
<UButton
2438
size="xs"
2539
:disabled="disabled"
2640
:loading="disabled"
27-
@click="emits('newThread')"
41+
@click="maybeEmit('newThread')"
2842
>New Exam</UButton
2943
>
3044
</div>

components/SidebarLinks.vue

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<script setup lang="ts">
2+
import SignUpModal from "./SignUpModal.vue";
3+
24
type NavLink = {
35
label: string;
46
icon: string;
@@ -15,6 +17,20 @@ const emits = defineEmits<{
1517
(e: "newThread"): void;
1618
(e: "newExam"): void;
1719
}>();
20+
21+
const { guestMode, setShowSignUpModal } = useAuth();
22+
23+
function maybeEmit(event: "newThread" | "newExam") {
24+
if (guestMode.value) {
25+
setShowSignUpModal(true);
26+
} else {
27+
if (event === "newExam") {
28+
emits("newExam");
29+
} else if (event === "newThread") {
30+
emits("newThread");
31+
}
32+
}
33+
}
1834
</script>
1935

2036
<template>
@@ -25,7 +41,7 @@ const emits = defineEmits<{
2541
size="xs"
2642
:disabled="disabled"
2743
:loading="disabled"
28-
@click="emits('newThread')"
44+
@click="maybeEmit('newThread')"
2945
>
3046
New Chat</UButton
3147
>
@@ -49,7 +65,7 @@ const emits = defineEmits<{
4965
size="xs"
5066
:disabled="disabled"
5167
:loading="disabled"
52-
@click="emits('newExam')"
68+
@click="maybeEmit('newExam')"
5369
>New Exam</UButton
5470
>
5571
</div>

components/SignUpModal.vue

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script lang="ts" setup>
2+
defineProps<{
3+
modelValue: boolean;
4+
}>();
5+
6+
const emits = defineEmits<{
7+
(e: "update:modelValue", payload: boolean): void;
8+
}>();
9+
</script>
10+
11+
<template>
12+
<UModal
13+
:modelValue="modelValue"
14+
@update:modelValue="(val) => emits('update:modelValue', val)"
15+
>
16+
<div class="p-8 text-center">
17+
<p class="my-4 mb-10">Please sign up to continue using StudyHQ.</p>
18+
<div class="flex justify-center mt-8 mb-4">
19+
<SignInGoogle class="mr-2" />
20+
21+
<SignInGithub />
22+
</div>
23+
</div>
24+
</UModal>
25+
</template>

composables/useAuth.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { ref } from "vue";
2+
3+
const guestMode = ref(true);
4+
const showSignUpModal = ref(false);
5+
6+
export function useAuth() {
7+
const setGuest = () => (guestMode.value = true);
8+
return {
9+
setShowSignUpModal: (val: boolean) => {
10+
showSignUpModal.value = val;
11+
},
12+
showSignUpModal,
13+
guestMode,
14+
setGuest,
15+
};
16+
}

layouts/default.vue

+23-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22
import { emitter } from "~/src/emitter";
33
import { useIntervalFn, useMagicKeys } from "@vueuse/core";
44
import SidebarLinks from "~/components/SidebarLinks.vue";
5+
import { useAuth } from "~/composables/useAuth";
6+
import SignUpModal from "~/components/SignUpModal.vue";
7+
58
const { ctrl, n } = useMagicKeys();
9+
const { clear, loggedIn } = useUserSession();
10+
const { guestMode, setShowSignUpModal, showSignUpModal } = useAuth();
11+
12+
if (!loggedIn.value && !guestMode.value) {
13+
await navigateTo("/");
14+
}
615
716
const { data: threads, refresh: refreshThreads } =
817
await useFetch("/api/threads");
@@ -15,17 +24,11 @@ declare global {
1524
1625
const isOpen = ref(false);
1726
18-
const { clear, loggedIn } = useUserSession();
19-
2027
const { loading: signingOut, run: handleSignOut } = useLoading(async () => {
2128
await clear();
2229
await navigateTo("/");
2330
});
2431
25-
if (!loggedIn.value) {
26-
await navigateTo("/");
27-
}
28-
2932
const { data: user, refresh: refreshUserData } = await useFetch("/api/user");
3033
3134
// useIntervalFn(() => {
@@ -69,13 +72,21 @@ const examLinks = computed(() =>
6972
const { run: _handleNewThread, loading: creatingNewThread } = useCreateThread();
7073
7174
async function handleNewThread() {
72-
await _handleNewThread();
73-
isOpen.value = false;
75+
if (guestMode.value) {
76+
setShowSignUpModal(true);
77+
} else {
78+
await _handleNewThread();
79+
isOpen.value = false;
80+
}
7481
}
7582
7683
async function handleNewExam() {
77-
isOpen.value = false;
78-
await navigateTo(`/exams/new`);
84+
if (guestMode.value) {
85+
setShowSignUpModal(true);
86+
} else {
87+
isOpen.value = false;
88+
await navigateTo(`/exams/new`);
89+
}
7990
}
8091
8192
watchEffect(() => {
@@ -96,6 +107,7 @@ const credit = computed(() => {
96107

97108
<template>
98109
<UContainer class="pt-4">
110+
<SignUpModal v-model="showSignUpModal" />
99111
<div class="flex justify-between items-center w-full mb-4 mx-2">
100112
<NuxtLink
101113
class="font-mono mr-4"
@@ -122,7 +134,7 @@ const credit = computed(() => {
122134
@click="() => (isOpen = true)"
123135
/>
124136
<USlideover v-model="isOpen">
125-
<div>
137+
<div class="overflow-scroll">
126138
<div class="flex items-center justify-between mt-4 mx-2">
127139
<UButton
128140
@click="handleSignOut"

mydb.sqlite

Whitespace-only changes.

0 commit comments

Comments
 (0)