Skip to content

Commit

Permalink
Merge new functionality "fiches" (part 1) of #39 from camarm-dev/dev
Browse files Browse the repository at this point in the history
Nouvelle fonctionnalité "fiches" (partie 1)
  • Loading branch information
camarm-dev authored Dec 15, 2023
2 parents ca4ab50 + da3270f commit cbde186
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 5 deletions.
2 changes: 1 addition & 1 deletion app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</ion-item>
</ion-menu-toggle>
<ion-menu-toggle :auto-hide="false">
<ion-item @click="goTo('/fiches')" disabled lines="none" :detail="false" class="hydrated" :class="path === '/fiches' ? 'selected': ''">
<ion-item @click="goTo('/fiches')" lines="none" :detail="false" class="hydrated" :class="path === '/fiches' ? 'selected': ''">
<ion-icon aria-hidden="true" slot="start" :icon="documentOutline"></ion-icon>
<ion-label>Fiches</ion-label>
</ion-item>
Expand Down
120 changes: 120 additions & 0 deletions app/src/components/FicheModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<script setup lang="ts">
import {
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonTitle,
IonToolbar,
IonButton,
IonNavLink,
IonLabel, IonBadge,
} from "@ionic/vue";
import {chevronBackOutline, pushOutline, shareOutline} from "ionicons/icons";
</script>

<template>
<ion-header :translucent="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-nav-link router-direction="back">
<ion-button @click="navigateBack()">
<ion-icon class="ion-no-margin" :icon="chevronBackOutline" slot="start"/>
Retour
</ion-button>
</ion-nav-link>
</ion-buttons>
<ion-title>{{ nom }}</ion-title>
<ion-buttons slot="end">
<ion-button @click="shareSheet()">
<ion-icon slot="icon-only" :icon="shareOutline"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true" class="ion-padding">
<ion-header collapse="condense">
<ion-toolbar>
<ion-label>
<ion-title class="remede-font ion-wrap" size="large">{{ nom }}</ion-title>
</ion-label>
<ion-buttons slot="end">
<ion-button @click="openCredits()">
<ion-icon slot="icon-only" :icon="pushOutline" color="medium"/>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-label>
<p class="ion-padding-start">{{ description }}</p>
</ion-label>
<div class="ion-padding">
<ion-badge class="ion-margin-end" :color="getTagColor(tag)" v-for="tag in tags">{{ tag }}</ion-badge>
</div>
<br>
<div class="ion-padding" v-html="contenu"/>
</ion-content>
</template>

<script lang="ts">
import {useIonRouter} from "@ionic/vue";
import {defineComponent} from "vue";
import {Share} from "@capacitor/share";
export default defineComponent({
props: ['nom', 'description', 'contenu', 'tags', 'credits', 'slug'],
data() {
return {
navigateBack: () => "" as Function
}
},
mounted() {
const ionRouter = useIonRouter()
function navigateBackIfNoHistory() {
if (!ionRouter.canGoBack()) {
ionRouter.navigate('/fiches', 'back', 'replace')
}
}
this.navigateBack = navigateBackIfNoHistory
},
methods: {
goTo(path: string) {
this.$router.push(path)
},
openCredits() {
window.open(this.credits)
},
async shareSheet() {
try {
await Share.share({
title: `"${this.nom}" sur Remède`,
text: `La fiche de français "${this.nom}" est sur Remède !`,
url: `https://remede.camam.fr/fiches/${this.slug}`,
dialogTitle: 'Partager la fiche',
})
} catch {
alert('Fonctionnalité non supportée par votre navigateur')
}
},
getTagColor(tag: string) {
switch (tag) {
case 'orthographe':
return 'primary'
case 'grammaire':
return 'success'
case 'lexique':
return 'tertiary'
case 'conjugaison':
return 'secondary'
case 'style':
return 'warning'
case 'typographie':
return 'danger'
default:
return 'grey'
}
}
}
})
</script>
5 changes: 4 additions & 1 deletion app/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ const routes: Array<RouteRecordRaw> = [
path: '/dictionnaire/:mot',
component: () => import ('../views/WordPage.vue')
},

{
path: '/fiches/:slug',
component: () => import ('../views/FichePage.vue')
},
{
path: '/',
component: Outlet,
Expand Down
37 changes: 37 additions & 0 deletions app/src/views/FichePage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<ion-page>
<FicheModal v-bind="fiche" />
</ion-page>
</template>

<script setup lang="ts">
import { IonPage } from '@ionic/vue';
import FicheModal from "@/components/FicheModal.vue";
</script>

<script lang="ts">
export default {
data() {
return {
fiche: {
contenu: '',
description: 'La fiche n\'a pas été trouvée !',
nom: 'Pas de fiche',
tags: [],
slug: '',
credits: ''
}
}
},
mounted() {
this.loadSheet()
},
methods: {
async loadSheet() {
this.fiche = await fetch(`https://api-remede.camarm.fr/sheets/${this.$route.params.slug}`).then(resp => resp.json())
}
}
}
</script>

76 changes: 75 additions & 1 deletion app/src/views/FichesPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,28 @@
<ion-toolbar>
<ion-title size="large">Fiches</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-searchbar disabled placeholder="Rechercher une fiche"></ion-searchbar>
<ion-progress-bar v-if="loading" type="indeterminate" color="medium" style="width: 95%; margin: auto"></ion-progress-bar>
</ion-toolbar>
</ion-header>

<ion-note>Rien ici pour le moment...</ion-note>
<ion-refresher slot="fixed" @ionRefresh="handleRefresh($event)">
<ion-refresher-content></ion-refresher-content>
</ion-refresher>

<ion-note class="ion-padding ion-float-end" v-if="failed">Fonctionne seulement avec une connexion internet !</ion-note>
<ion-nav-link router-direction="forward" :component="FicheModal" :component-props="sheet" v-for="sheet in sheets">
<ion-list inset>
<ion-item button color="light" lines="none">
<ion-label>
<h1>{{ sheet.nom }}</h1>
<p>{{ sheet.description }}</p>
<ion-badge class="ion-margin-end" :color="getTagColor(tag)" v-for="tag in sheet.tags">{{ tag }}</ion-badge>
</ion-label>
</ion-item>
</ion-list>
</ion-nav-link>
</ion-content>
</ion-page>
</template>
Expand All @@ -30,5 +48,61 @@ import {
IonPage,
IonTitle,
IonToolbar,
IonSpinner,
IonItem,
IonLabel,
IonList,
IonBadge, IonNavLink, IonProgressBar, IonSearchbar
} from '@ionic/vue';
import FicheModal from "@/components/FicheModal.vue";
</script>

<script lang="ts">
export default {
data() {
return {
loading: true,
failed: false,
sheets: []
}
},
mounted() {
this.loadSheets()
},
methods: {
async loadSheets() {
this.loading = true
try {
this.sheets = await fetch('https://api-remede.camarm.fr/sheets').then(resp => resp.json())
this.failed = false
} catch {
this.failed = true
}
this.loading = false
},
getTagColor(tag: string) {
switch (tag) {
case 'orthographe':
return 'primary'
case 'grammaire':
return 'success'
case 'lexique':
return 'tertiary'
case 'conjugaison':
return 'secondary'
case 'style':
return 'warning'
case 'typographie':
return 'danger'
default:
return 'grey'
}
},
handleRefresh(event: CustomEvent) {
this.loadSheets().then(() => {
event.target.complete()
})
}
}
}
</script>
13 changes: 13 additions & 0 deletions data/fiches/Exemple.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
nom: Exemple de fiche
description: Ceci est la première fiche
credits: https://remede.camarm.fr/sheets-credits#example
slug: example
tags:
- grammaire
- orthographe
---

# Exemple

Ceci est un exemple de fiche. Les fiches continuellement améliorées et encore en train d'être écrites. Vous pouuvez contribuer sur [github](https://github.com/camarm-dev/remede).
56 changes: 55 additions & 1 deletion docs/EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Welcome on the documentation page of Remède ! Navigate through the contents bel
- [Dataset](#dataset)
- [Remede document schema](#remède-document-schema)
- [Sqlite Database](#sqlite-database)
- [Cheatsheets](#cheatsheets)

## Development

Expand Down Expand Up @@ -59,7 +60,7 @@ npm run dev
- Install python3
- Install dependencies
```shell
pip install fastapi uvicorn starlette
pip install fastapi uvicorn starlette python-frontmatter markdown
```
- Fetch database with Git LFS
```shell
Expand Down Expand Up @@ -174,3 +175,56 @@ His schema is:
- With fields
- word (`string`: the mot)
- document (`string`: the Remède document in JSON format)

### Cheatsheets

Cheatsheet containing french orthography and grammar lessons are written in the `data/fiches` folder.

They are written in `markdown` and use `fronr-matter` to work.

Cheatsheet example:

```markdown
---
nom: Exemple de fiche
description: Ceci est la première fiche
credits: https://remede.camarm.fr/sheets-credits#example
slug: exemple
tags:
- grammaire
- orthographe
---

# Exemple

Ceci est un exemple de fiche.
```

Available tags: `grammaire`, `orthographe`, `conjugaison`, `lexique`, `style`, `typographie`

Please don't forget that to credits one or many contributors, the page `https://remede.camarm.fr/sheets-credits`, placed in `docs/sheets-credits.md` is here to credit yourself and quote the source(s) that helped you.
- Here is how to correctly use this file
```markdown
[...]

## Credits

[//]: # (Begin new crédit)

### Exemple

- Author(s): [Nom](github link / website / wiki page / without link)
- Source: [Remède / Extern source name](remede github link / extern link)
[//]: # (If the source is remède, add)
- With help of [source name](source link)
- With help of [other source name](other source link)

[//]: # (Other fields available)

- File historic and contributions: [On Github](https://github.com/camarm-dev/remede/commits/main/data/fiches/<nom-fiche>.md)

[//]: # (End new credits)
```
- Your credits will be available at `https://remede.camarm.fr/sheets-credits#exemple`

Please fill correctly this file, because it tracks authors and contributions, and is here to respect privacy policies and copyrights about Rèmede and the sources of its data !
Loading

0 comments on commit cbde186

Please sign in to comment.