Skip to content

Commit

Permalink
list existing sets
Browse files Browse the repository at this point in the history
  • Loading branch information
kubo550 committed May 4, 2024
1 parent bfe3b4e commit 0fdeef6
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const logout = async () => {
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/create">Create</RouterLink>
<RouterLink to="/sets">Learn</RouterLink>

<RouterLink to="/register" v-if="!user">Register</RouterLink>
<RouterLink to="/login" v-if="!user">Login</RouterLink>
Expand Down
73 changes: 42 additions & 31 deletions src/components/SaveFlashcards.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script setup lang="ts">
import type { PropType } from 'vue'
import type { Phrase } from '@/lib/types'
import type { DbSet, Phrase } from '@/lib/types'
import { ref } from 'vue'
import { toast } from 'vue3-toastify'
import { getAuth } from 'firebase/auth'
import type { User } from 'firebase/auth'
import { getFirestore, collection, addDoc } from 'firebase/firestore'
const { phrases } = defineProps({
phrases: {
Expand All @@ -17,29 +18,32 @@ const isSaving = ref(false)
const error = ref<string | null>(null)
const isSaved = ref(false)
const auth = getAuth()
const setName = ref('')
const savedSetId = ref('')
const saveToFirestore = async (creator: User, setName: string, flashcards: Phrase[]) => {
const saveToFirestore = async (creator: User, name: string, flashcards: Phrase[]) => {
const data = {
creatorId: creator.uid,
creatorEmail: creator.email,
setName,
setName: name,
flashcards
}
} as DbSet
// Save data to Firestore
const db = getFirestore()
const savedDoc = await addDoc(collection(db, 'sets'), data)
return savedDoc.id
}
const saveFlashcardsSet = async (setName: string, flashcards: Phrase[]) => {
const user = auth.currentUser
if (!user) {
return
}
const saveFlashcardsSet = async () => {
const user = auth.currentUser!
try {
error.value = null
isSaving.value = true
isSaving.value = false
const savedId = await saveToFirestore(user, setName.value, phrases)
savedSetId.value = savedId
toast(`Flashcards set saved!`, {
type: 'success',
theme: 'dark',
Expand All @@ -50,6 +54,7 @@ const saveFlashcardsSet = async (setName: string, flashcards: Phrase[]) => {
} catch (e) {
error.value = 'Something went wrong. Please try again later.'
isSaving.value = false
console.error(e)
}
}
Expand Down Expand Up @@ -95,41 +100,47 @@ const handleCopyToClipboard = () => {
</v-carousel-item>
</v-carousel>

<!-- <v-btn-->
<!-- v-if="!isSaved"-->
<!-- :disabled="isSaving || isSaved"-->
<!-- variant="outlined"-->
<!-- class="mt-4"-->
<!-- @click="saveFlashcardsSet"-->
<!-- >-->
<!-- <v-icon icon="mdi-content-save" class="mr-2"></v-icon>-->
<!-- {{ isSaving ? 'Saving...' : 'Save' }}-->
<!-- </v-btn>-->

<!-- <v-btn v-if="isSaved" variant="outlined" class="mt-4" @click="isSaved = false">-->
<!-- <v-icon icon="mdi-lightbulb-on" class="mr-2"></v-icon>-->
<!-- Go to flashcards-->
<!-- </v-btn>-->
<v-text-field
v-model="setName"
class="input"
:disabled="isSaved"
:rules="[() => !!setName || 'Set name is required']"
label="Set name"
placeholder="My first set"
></v-text-field>

<v-btn
v-if="!isSaved"
:disabled="isSaving || isSaved"
:disabled="isSaving || isSaved || !setName || !phrases.length"
variant="outlined"
class="mt-4"
@click="handleCopyToClipboard"
@click="saveFlashcardsSet"
>
<v-icon icon="mdi-content-save" class="mr-2"></v-icon>
Copy to clipboard
{{ isSaving ? 'Saving...' : 'Save set' }}
</v-btn>

<!-- <v-btn v-if="isSaved" variant="outlined" class="mt-4" @click="isSaved = false; ">-->
<!-- <v-icon icon="mdi-lightbulb-on" class="mr-2"></v-icon>-->
<!-- Go to flashcards-->
<!-- </v-btn>-->

<a v-if="isSaved" :href="`/sets/${savedSetId}`">
<v-btn variant="outlined" class="mt-4">
<v-icon icon="mdi-lightbulb-on" class="mr-2"></v-icon>
Go to flashcards
</v-btn>
</a>

<v-btn
v-if="!isSaved"
:disabled="isSaving || isSaved"
variant="outlined"
class="mt-4"
@click="saveFlashcardsSet"
@click="handleCopyToClipboard"
>
Save set
<v-icon icon="mdi-content-copy" class="mr-2"></v-icon>
Copy to clipboard
</v-btn>
</v-container>
</template>
Expand Down
8 changes: 8 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ export type Phrase = {
phrase?: string
meaning?: string
}

export type DbSet = {
id?: string
creatorId: string
creatorEmail: string | null
setName: string
flashcards: Required<Phrase>[]
}
13 changes: 12 additions & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createRouter, createWebHistory } from 'vue-router'
import { getAuth, onAuthStateChanged } from 'firebase/auth'
import HomeView from '../views/HomeView.vue'
import CreateView from '../views/CreateView.vue'
import LearnView from '@/views/LearnView.vue'
import RegisterView from '@/views/RegisterView.vue'
import LoginView from '@/views/LoginView.vue'
import { getAuth, onAuthStateChanged } from 'firebase/auth'
import FlashCardsView from '@/views/FlashCardsView.vue'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
Expand Down Expand Up @@ -36,6 +37,16 @@ const router = createRouter({
path: '/register',
name: 'register',
component: RegisterView
},
{
path: '/sets',
name: 'flashcards',
component: FlashCardsView
},
{
path: '/sets/:id',
name: 'learn',
component: LearnView
}
]
})
Expand Down
56 changes: 56 additions & 0 deletions src/views/FlashCardsView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { getFirestore, getDocs, collection } from 'firebase/firestore'
import type { DbSet } from '../lib/types'
const allSets = ref<DbSet[] | null>(null)
const getSets = async () => {
try {
const db = getFirestore()
const sets = await getDocs(collection(db, 'sets'))
allSets.value = sets.docs.map((doc) => ({
...doc.data(),
id: doc.id
})) as DbSet[]
} catch (e) {
console.error(e)
}
}
getSets()
</script>

<template>
<v-sheet class="container mt-10 p-10">
<v-card v-for="set in allSets" class="mx-auto my-12 grid" elevation="16" max-width="344">
<v-card-item>
<v-card-title> {{ set.setName }}</v-card-title>

<v-card-subtitle> {{ set.creatorEmail }}</v-card-subtitle>
</v-card-item>

<v-card-text>
{{ set.flashcards.map((flashcard) => flashcard.phrase).join(', ') }}
</v-card-text>

<v-card-actions>
<a :href="`/sets/${set.id}`">
<v-btn color="primary">Learn</v-btn>
</a>
</v-card-actions>
</v-card>
</v-sheet>
</template>
<style scoped>
.container {
width: 100vw;
min-height: 80vh;
display: grid;
}
.grid {
grid-template-columns: repeat(auto-fill, minmax(344px, 1fr));
gap: 16px;
}
</style>
33 changes: 30 additions & 3 deletions src/views/LearnView.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { getFirestore, doc, getDoc } from 'firebase/firestore'
import type { DbSet } from '../lib/types'
const router = useRouter()
const setId = router.currentRoute.value.params.id as string
const currentSet = ref<DbSet | null>(null)
const getSet = async (setId: string) => {
try {
const db = getFirestore()
const setRef = doc(db, 'sets', setId)
const setSnap = await getDoc(setRef)
if (setSnap.exists()) {
console.log(setSnap.data())
currentSet.value = setSnap.data() as DbSet
}
} catch (e) {
console.error(e)
}
}
getSet(setId)
</script>

<template>
<main>hello</main>
<v-sheet class="container">
<h1>TODO: add the same carousel component here</h1>
</v-sheet>
</template>

<style scoped></style>

0 comments on commit 0fdeef6

Please sign in to comment.