Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found

Cible

Sélectionner le projet cible
  • sbibauw/languagelab
1 résultat
Afficher les modifications
Validations sur la source (17)
Affichage de
avec 906 ajouts et 102 suppressions
# Instructions pour les tuteurs
## Section xxxx
- pas clair : ????
## Foire aux questions
### Pourquoi il n'y pas de réactions/likes (👍) sur les messages ?
Parce qu'on veut vous faire parler.
......@@ -10,6 +10,9 @@ sqlalchemy.url = sqlite:///languagelab.sqlite
[post_write_hooks]
hooks = black
black.type = console_scripts
black.entrypoint = black
black.options = -l 79
[loggers]
keys = root,sqlalchemy,alembic
......
"""Add code column to test_typing table
Revision ID: fe09c6f768cd
Revises: 9038306d44fc
Create Date: 2025-01-31 21:45:56.343739
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "fe09c6f768cd"
down_revision: Union[str, None] = "0bf670c4a564"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"_tmp_test_typing",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.Column("code", sa.String(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.drop_table("test_typing")
op.rename_table("_tmp_test_typing", "test_typing")
......@@ -263,8 +263,8 @@ def delete_message_feedback(db: Session, feedback_id: int):
db.commit()
def create_test_typing(db: Session, test: schemas.TestTypingCreate, user: schemas.User):
db_test = models.TestTyping(user_id=user.id)
def create_test_typing(db: Session, test: schemas.TestTypingCreate):
db_test = models.TestTyping(code=test.code)
db.add(db_test)
db.commit()
db.refresh(db_test)
......
......@@ -290,28 +290,14 @@ def store_typing_entries(
pass
@usersRouter.post("/{user_id}/tests/typing", status_code=status.HTTP_201_CREATED)
@studyRouter.post("/typing", status_code=status.HTTP_201_CREATED)
def create_test_typing(
user_id: int,
test: schemas.TestTypingCreate,
background_tasks: BackgroundTasks,
db: Session = Depends(get_db),
current_user: schemas.User = Depends(get_jwt_user),
):
if (
not check_user_level(current_user, models.UserType.ADMIN)
and current_user.id != user_id
):
raise HTTPException(
status_code=401,
detail="You do not have permission to create a test for this user",
)
db_user = crud.get_user(db, user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
typing_id = crud.create_test_typing(db, test, db_user).id
typing_id = crud.create_test_typing(db, test).id
if test.entries:
background_tasks.add_task(store_typing_entries, db, test.entries, typing_id)
......
......@@ -181,8 +181,8 @@ class TestTyping(Base):
__tablename__ = "test_typing"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), index=True)
created_at = Column(DateTime, default=datetime_aware)
code = Column(String)
entries = relationship("TestTypingEntry", backref="typing")
......@@ -287,7 +287,6 @@ class Study(Base):
start_date = Column(DateTime)
end_date = Column(DateTime)
chat_duration = Column(Integer)
typing_test = Column(Boolean)
users = relationship("User", secondary="study_users", back_populates="studies")
surveys = relationship(
......
......@@ -225,6 +225,7 @@ class TestTypingEntryCreate(BaseModel):
class TestTypingCreate(BaseModel):
entries: list[TestTypingEntryCreate]
code: str
class TestVocabularyCreate(BaseModel):
......
......@@ -167,7 +167,7 @@
"complete": "Thank you for participating!",
"score": "Score: ",
"code": "Your code:",
"codeIndication": "The instructor should have given you a personal code. If not, please write your email address.",
"codeIndication": "The instructor should have given you a personal code.<br>If not, please write your email address.",
"invalidCode": "Invalid code",
"birthYear": "The year you were born",
"gender": "What gender do you identify as?",
......@@ -199,7 +199,7 @@
"privacyD": "The data collected (your answers to the various questions) will be treated confidentially and anonymously. \nThey will be kept after their complete anonymization and can only be used for scientific or educational purposes. \nThey may possibly be shared with other researchers or teachers, but always within this strictly research or teaching framework.",
"rights": "What are your rights? \nVoluntary participation and possible withdrawal",
"rightsD": "Your participation in this study is voluntary. \nYou can decide to no longer participate in the study at any time without having to give a reason. \nYou can also request that your data be deleted at any time. \nIf you have any questions or concerns regarding this study, you can contact the study leader, Serge Bibauw, at the following address:",
"title": "Information document and informed consent"
"title": "Study information and informed consent"
},
"introduction": "This is a questionnaire.",
"invalidEmail": "Invalid email address",
......
Ce diff est replié.
......@@ -238,7 +238,8 @@
},
"tests": {
"sendResults": "Envoyer",
"sendResultsDone": "Envoyé"
"sendResultsDone": "Envoyé",
"typing": "Test de frappe"
},
"surveys": {
"introduction": "Ceci est un questionnaire.",
......@@ -249,10 +250,10 @@
"complete": "Merci pour votre participation !",
"score": "Score : ",
"code": "Votre code :",
"codeIndication": "L'instructeur devrait vous avoir donné un code personnel. Si ce n'est pas le cas, veuillez indiquer votre adresse électronique.",
"codeIndication": "L'instructeur devrait vous avoir donné un code personnel.<br>Sinon, indiquez votre adresse e-mail.",
"invalidCode": "Code invalide",
"consent": {
"title": "Document d’information et consentement éclairé",
"title": "Informations sur l'étude et consentement éclairé",
"intro": "Vous êtes invité·e à participer à une étude scientifique pour concevoir, valider et appliquer des tests de vocabulaire.",
"participation": "Qu'implique votre participation ?",
"participationD": "Si vous acceptez de participer, vous devrez seulement répondre à ce questionnaire et éventuellement à un autre test, si indiqué par la personne qui administre le test.",
......
{
"admin": {
"actions": "Acties",
"passwordPrompt": "Voer het wachtwoord in. \nHoud er rekening mee dat dit niet meer kan worden verhaald."
},
"button": {
"cancel": "Annuleren",
"close": "Dichtbij",
"continue": "Doorgaan",
"create": "Creëren",
"delete": "VERWIJDEREN",
"login": "Inloggen",
"next": "Volgende",
"remove": "Terugtrekken",
"save": "Om te beschermen",
"sent": "Verstuurd !",
"start": "Om te beginnen",
"submit": "Versturen",
"thank-you": "BEDANKT !",
"tryit": "Om te proberen",
"update": "Om bij te werken",
"updated": "Bijgewerkt!"
},
"chatbox": {
"deleteFeedback": "Weet je zeker dat je deze feedback wilt verwijderen? \nDeze actie is onomkeerbaar.",
"disabled": "Deze sessie is alleen voor de goede orde zichtbaar.",
"edited": "gewijzigd",
"history": "Historisch",
"placeholder": "Schrijf hier uw bericht...",
"replyingTo": "In reactie op:",
"sendError": "Fout bij het verzenden van het bericht"
},
"header": {
"admin": {
"sessions": "Sessies",
"studies": "Studies",
"users": "Gebruikers"
},
"appName": "Languagelab",
"availability": "Beschikbaarheid",
"connectedAs": "Verbonden als",
"language": "Taal",
"metadataWarning": "Vul het registratieformulier in voordat u de applicatie gebruikt.",
"register": "Register",
"signin": "Inloggen",
"signout": "Loskoppelen",
"tutorSelection": "Onderwijzer"
},
"home": {
"actions": "Acties",
"add": "Toevoegen",
"bookSession": "Reserveer een sessie",
"bookingFailed": "Fout bij het boeken van de sessie",
"bookingSuccessful": "Sessie succesvol geboekt",
"confirm": "Bevestigen",
"createSession": "Onmiddellijke sessie",
"currentSessions": "Huidige sessies",
"date": "Datum",
"deleteSessionConfirm": "Weet u zeker dat u deze sessie wilt verwijderen? \nDeze actie is onomkeerbaar.",
"email": "E-mail",
"learningLanguage": "Doeltaal",
"newContact": "Voeg een contactpersoon toe",
"newFirstContact": "Voeg een eerste contact toe",
"nickname": "Naam",
"noContact": "Voeg contact toe om te starten",
"noCurrentOrFutureSessions": "Er zijn geen sessies gaande of gepland",
"noSessions": "Geen sessie",
"participantPlaceholder": "Kiezen",
"participants": "Deelnemers",
"pastSessions": "Voltooide sessies",
"plannedSessions": "Geplande sessies",
"remainingDuration": "Resterende tijd",
"sessionAdded": "Je bent toegevoegd aan een sessie met {users}",
"sessionEnded": "Afgerond"
},
"inputs": {
"range": {
"1": "Geen manier",
"2": "Een beetje",
"3": "Matig",
"4": "Veel",
"5": "Enorm"
}
},
"login": {
"email": "E-mail",
"login": "Inloggen",
"noAccountLink": "Registreer hier"
},
"register": {
"confirmPassword": "Bevestig wachtwoord",
"confirmTutor": "Bevestig je dat je '{NAME}' als je voogd hebt geselecteerd?",
"consent": {
"intro": "U wordt uitgenodigd om deel te nemen aan een wetenschappelijk onderzoek. \nHet doel van deze studie is om te begrijpen hoe docenten en leerlingen in vreemde talen communiceren tijdens online tutorssessies. \nDe verzamelde gegevens zullen worden gebruikt om online tutoring -tools te verbeteren en om de cognitieve processen aan beide zijden beter te begrijpen.",
"ok": "Ik ga akkoord met deelname aan het onderzoek zoals hierboven beschreven.",
"participation": "Wat betreft uw deelname?",
"participationD": "Als u akkoord gaat met deelname, wordt u uitgenodigd om deel te nemen aan online bijlessessies met een docent vreemde talen. \nOok wordt u gevraagd om voor en na de bijlessessies vragenlijsten in te vullen. \nBegeleidingssessies worden opgenomen voor latere analyse.</p><p>We vragen dat je van plan bent om minimaal <strong>8 sessies van een uur</strong> bijles te geven (dus 8 uur in totaal), over een periode van periode van 1 tot 3 maanden. \nAls je wilt, kun je er uiteraard meer maken. \nU kunt echter op ieder moment stoppen met deelname aan het onderzoek.",
"privacy": "Hoe worden uw gegevens verwerkt en opgeslagen?",
"privacyD": "De verzamelde gegevens (bijvoorbeeld transcripties van gesprekken, testresultaten, opvallende maatregelen, informatie over deelnemers zoals leeftijd of geslacht) zullen op een vertrouwelijke en anonieme manier worden verwerkt. \nZe zullen worden bewaard na hun volledige anonimisering en kunnen alleen worden gebruikt voor wetenschappelijke of educatieve doeleinden. \nZe kunnen mogelijk worden gedeeld met andere onderzoekers of leraren, maar altijd in dit strikt onderzoeks- of onderwijskader.",
"rights": "Wat zijn uw rechten? \nVrijwillige deelname en mogelijke terugtrekking",
"rightsD": "Uw deelname aan dit onderzoek is vrijwillig. \nU kunt besluiten om niet op elk gewenst moment deel te nemen aan het onderzoek zonder uzelf te rechtvaardigen. \nU kunt ook vragen om uw gegevens op elk gewenst moment te verwijderen. \nAls u vragen of zorgen over deze studie hebt, kunt u contact opnemen met de studiemanager, Serge Bibauw, op het volgende adres:",
"studyData": {
"address": "Adres",
"addressD": "Plaats kardinaal Mercier 14, 1348 Louvain-la-neuve",
"email": "E-mail",
"emailD": "serge.bibauw@uclouvain.be",
"person": "Studie leider",
"personD": "Serge Bibauw",
"project": "Onderzoeksproject",
"projectD": "AI Tutoring in Language Learning (FNRS CDR 2024-2026)",
"study": "Titel van de studie",
"studyD": "Longitudinale studie van begeleiding in vreemde taal",
"title": "Bestudeerinformatie",
"university": "Universiteit",
"universityD": "Katholieke Universiteit van Louvain (Uclouvain)"
},
"title": "Geïnformeerde informatie- en toestemmingsdocument"
},
"consentTutor": {
"intro": "U wordt uitgenodigd om deel te nemen aan een wetenschappelijk onderzoek. \nHet doel van dit onderzoek is om te begrijpen hoe docenten en studenten van vreemde talen met elkaar omgaan tijdens online bijlessessies. \nDe verzamelde gegevens zullen worden gebruikt om online bijlestools te verbeteren en om cognitieve processen aan beide kanten beter te begrijpen.",
"ok": "Ik ga akkoord met deelname aan het onderzoek zoals hierboven beschreven.",
"participation": "Wat betreft uw deelname?",
"participationD": "Als u akkoord gaat met deelname, wordt u uitgenodigd om deel te nemen aan online bijlessessies met een docent vreemde talen. \nOok wordt u gevraagd om voor en na de bijlessessies vragenlijsten in te vullen. \nBegeleidingssessies worden opgenomen voor latere analyse.</p><p>We vragen dat je van plan bent om minimaal <strong>8 sessies van een uur</strong> bijles te geven (dus 8 uur in totaal), over een periode van periode van 1 tot 3 maanden. \nAls je wilt, kun je er uiteraard meer maken. \nU kunt echter op ieder moment stoppen met deelname aan het onderzoek.",
"privacy": "Hoe worden uw gegevens verwerkt en bewaard?",
"privacyD": "De verzamelde gegevens (bijvoorbeeld transcripties van gesprekken, testresultaten, opvallende maatregelen, informatie over deelnemers zoals leeftijd of geslacht) zullen op een vertrouwelijke en anonieme manier worden verwerkt. \nZe zullen worden bewaard na hun volledige anonimisering en kunnen alleen worden gebruikt voor wetenschappelijke of educatieve doeleinden. \nZe kunnen mogelijk worden gedeeld met andere onderzoekers of leraren, maar altijd in dit strikt onderzoeks- of onderwijskader.",
"rights": "Wat zijn uw rechten? \nVrijwillige deelname en mogelijke terugtrekking",
"rightsD": "Uw deelname aan dit onderzoek is vrijwillig. \nU kunt op ieder moment besluiten om niet meer deel te nemen aan het onderzoek, zonder dat u hiervoor een reden hoeft op te geven. \nDaarnaast kunt u op ieder moment verzoeken om uw gegevens te verwijderen. \nAls u vragen of opmerkingen heeft over dit onderzoek, kunt u contact opnemen met de onderzoeksleider, Serge Bibauw, op het volgende adres:",
"studyData": {
"address": "Adres",
"addressD": "Plaats kardinaal Mercier 14, 1348 Louvain-la-Neuve",
"email": "E-mail",
"emailD": "serge.bibauw@uclouvain.be",
"person": "Studie leider",
"personD": "Serge Bibauw",
"project": "Onderzoeksproject",
"projectD": "AI-begeleiding bij het leren van talen (FNRS CDR 2024-2026)",
"study": "Studietitel",
"studyD": "Longitudinaal onderzoek naar bijles in vreemde talen",
"title": "Bestudeerinformatie",
"university": "Universiteit",
"universityD": "Katholieke Universiteit van Louvain (Uclouvain)"
},
"title": "Informatiedocument en geïnformeerde toestemming"
},
"continue": "Auts Sint en Nihil Aut. \nQuia nihil eos rerum neque oefeningem molestiae. \nAut Ab Accidentium consequatur Rerum Architecto Voluptas. \nRefudiandae minima nemo vitae tempore. \nMoletiae Rerum aliquid UT Fugit eligendi. \nTempore Eum Id Nobis Sunt Deleniti en niet Ducimus. \nMaiRes Perferendis was niet overeengekomen Nostrum. \nOdio itaque Fugiat nr. \nLabriosam Sint Voluptatem Aut Placeat en Perferendis. \nSed quam voluptatem nodigatiBus quia dolorum. \nEius is Nihil Natus Modi Natus Quisquam Ut Impedit. \nTempore Enim Autem Laboriosam Sequi Ipsum quo. \n<Bold Class = \"Font-Bold\"> Aut Voluptatum Debitis en Aliquam Vel Rerum Facere.",
"continueButton": "Ga verder naar testen",
"email": {
"note": "",
"ph": ""
},
"error": {
"differentPasswords": "Wachtwoorden komen niet overeen",
"emailRules": "Voer een geldig e-mailadres in",
"emptyFields": "Vul alle velden in",
"humanity": "Bevestig dat u geen robot bent",
"metadata": "Controleer of u alle velden correct hebt gevuld"
},
"password": {
"note": ""
},
"signup": "Register",
"start": "Auts Sint en Nihil Aut. \nQuia nihil eos rerum neque oefeningem molestiae. \nAut Ab Accidentium consequatur Rerum Architecto Voluptas. \nRefudiandae minima nemo vitae tempore. \nMoletiae Rerum aliquid UT Fugit eligendi. \nAlias ​​Dolorum Quia Voluptatum Veniam Harum Aut welke en. \nVoluptatibus adipisci illo velt Apportenda. \nAsperiores accumus deserunt ontwikkeling adipisci expreesit. \nDucimus placeat zit Reversereit ea eos quam. \nUt facilis quia dégitiis odit unde temporibus error. \nNeque Sapiente UT vergelijkbaar. \nEius ut sapiente maxime dolor is Voluptatem Eum. \nVeniam Aut Quo. \nQuibusdam sed Numquam en Rem. \nTempore Eum Id Nobis Sunt Deleniti en niet Ducimus. \nMaiRes Perferendis was niet overeengekomen Nostrum. \nOdio itaque Fugiat nr. \nLabriosam Sint Voluptatem Aut Placeat en Perferendis. \nSed quam voluptatem nodigatiBus quia dolorum. \nEius is Nihil Natus Modi Natus Quisquam Ut Impedit. \nTempore Enim Autem Laboriosam Sequi Ipsum quo. \n<Bold Class = \"Font-Bold\"> Aut Voluptatum Debitis en Aliquam Vel Rerum Facere.",
"startButton": "Om te beginnen",
"startFastButton": "Begin direct met het gebruiken van de app",
"tab": {
"continue": "Doorgaan",
"information": "Informatie",
"signup": "Registratie",
"start": "Om te beginnen",
"study": "Studie"
}
},
"session": {
"downloadAllFeedbacks": "Download alle feedbacks",
"downloadAllMessages": "Download alle gesprekken",
"downloadAllMetadata": "Download alle metadata",
"errors": {
"addUser": "Fout bij toevoegen van gebruiker aan sessie",
"create": "Fout bij het maken van de sessie",
"delete": "Fout bij verwijderen van sessie",
"presence": "Fout bij het verzenden van de aanwezigheid",
"removeUser": "Fout bij het verwijderen van een gebruiker uit de sessie",
"typing": "Fout bij het verzenden van de invoerindicator"
},
"feedbackInline": "Feedback is toegevoegd aan",
"modal": {
"satisfy": {
"q1": "Hoe nuttig is deze toepassing?",
"q2": "Hoe gemakkelijk is deze toepassing gemakkelijk te gebruiken?",
"q3": "Mogelijke opmerkingen",
"success": "Uw antwoorden zijn opgenomen. \nBedankt voor je deelname!",
"title": "Tevredenheidsvragenlijst"
},
"weekly": {
"answers": {
"0": "Geen",
"1": "1 uur",
"2": "2 uur",
"3": "3 uur",
"4": "4 uur",
"5": "5 uur",
"6": "6 uur",
"7": "7 uur",
"8": "8 uur",
"9": "9 uur",
"10": "10 uur of meer",
"05": "30 minuten of minder",
"placeholder": ""
},
"description": "In de laatste 7 dagen ...",
"errors": {
"null": "Beantwoord alle vragen",
"submit": "Fout bij verzenden vragenlijst",
"toggle": "Fout bij het activeren of deactiveren van de sessie"
},
"questions[0]": "Hoeveel uur <b>cursus</b> in het {lang} heeft u gevolgd?",
"questions[1]": "Hoeveel uur heb je video's bekeken </b> in {lang} (films, serie, youtube ...) of <b> luisterde naar inhoud </b> in {lang} (podcasts, radio -radio, universitaire cursussen .. .)?",
"questions[2]": "Hoeveel uur heeft u <b>teksten gelezen</b> in het {lang} (boek, krant, strips, websites, enz.)?"
}
}
}
}
......@@ -77,3 +77,19 @@ export async function removeUserToStudyAPI(
});
return response.ok;
}
export async function createTestTypingAPI(
fetch: fetchType,
entries: typingEntry[],
code: string
): Promise<number | null> {
const response = await fetch(`/api/studies/typing`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ entries, code })
});
if (!response.ok) return null;
return parseInt(await response.text());
}
import type { fetchType } from '$lib/utils/types';
export async function sendTestVocabularyAPI(data: any): Promise<boolean> {
const response = await fetch(`/api/tests/vocabulary`, {
method: 'POST',
......
......@@ -87,22 +87,6 @@ export async function patchUserAPI(fetch: fetchType, user_id: number, data: any)
return response.ok;
}
export async function createTestTypingAPI(
fetch: fetchType,
user_id: number,
entries: typingEntry[]
): Promise<number | null> {
const response = await fetch(`/api/users/${user_id}/tests/typing`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ entries })
});
if (!response.ok) return null;
return parseInt(await response.text());
}
export async function createWeeklySurveyAPI(
fetch: fetchType,
user_id: number,
......
<script lang="ts">
import { t } from '$lib/services/i18n';
import Typingbox from '$lib/components/tests/typingbox.svelte';
import { get } from 'svelte/store';
import { createTestTypingAPI } from '$lib/api/users';
import type User from '$lib/types/user';
import { toastWarning } from '$lib/utils/toasts';
import { get } from 'svelte/store';
import { createTestTypingAPI } from '$lib/api/studies';
let { user, onFinish }: { user: User; onFinish: Function } = $props();
let { user, onFinish }: { user: User | null; onFinish: Function } = $props();
let data: typingEntry[] = $state([]);
let currentExercice = $state(0);
let inProgress = $state(false);
let exercices = [
{
duration: 15,
explications: `Repetez les lettres "dk" autant de fois que possible en 15 secondes. Le chronomètre démarre dès que vous appuyez sur une touche ou sur le boutton ${get(t)('button.start')}. Une vois que vous aurez terminé, appuyez sur le bouton ${get(t)('button.next')} pour passer à l'exercice suivant.`,
text: 'dk'.repeat(150) + '...'
duration: 30,
explications: 'Répétez la phrase suivante autant de fois que possible en 30 secondes.',
text: 'une femme folle tenait un verre dans sa main\n'.repeat(12) + '...'
},
{
duration: 30,
explications: 'Repetez la phrase suivante autant de fois que possible en 30 secondes.',
text: 'Le chat est sur le toit.\n'.repeat(20) + '...'
explications: 'Répétez la phrase suivante autant de fois que possible en 30 secondes.',
text: 'the cat was sleeping under the apple tree\n'.repeat(12) + '...'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'trois heures raisonnables\n'.repeat(6) + 'trois heures raisonnables'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'huit histoires profondes\n'.repeat(6) + 'huit histoires profondes'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'deux besoins fantastiques\n'.repeat(6) + 'deux besoins fantastiques'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'six bijoux bizarres\n'.repeat(6) + 'six bijoux bizarres'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'four interesting questions\n'.repeat(6) + 'four interesting questions'
},
{
duration: -1,
explications: 'Repetez 7 fois la phrase suivante le plus rapidement possible.',
text: 'Six animaux mangent\n'.repeat(6) + 'Six animaux mangent'
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'seven wonderful surprises\n'.repeat(6) + 'seven wonderful surprises'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'five important behaviours\n'.repeat(6) + 'five important behaviours'
},
{
duration: -1,
explications: 'Écrivez 7 fois la phrase suivante.',
text: 'some awkward zigzags\n'.repeat(6) + 'some awkward zigzags'
},
{
duration: -1,
explications: 'Finalement, écrivez une fois les caractères suivant.',
text: 'tjxgfl pgkfkq dtdrgt npwdvf'
}
];
async function submit() {
const res = await createTestTypingAPI(fetch, user.id, data);
if (!code) return;
const res = await createTestTypingAPI(fetch, data, code);
if (!res) return;
onFinish();
}
let step = $state(user ? 1 : 0);
let code: string | undefined = $state(user ? user.email : undefined);
function checkCode() {
if (!code) {
toastWarning(get(t)('surveys.invalidCode'));
return;
}
if (code.length < 3) {
toastWarning(get(t)('surveys.invalidCode'));
return;
}
step += 1;
}
</script>
{#each exercices as _, i (i)}
{#if i === currentExercice}
<Typingbox
exerciceId={i}
initialDuration={exercices[i].duration}
explications={exercices[i].explications}
text={exercices[i].text}
bind:data
bind:inProgress
onFinish={() => {
inProgress = false;
setTimeout(() => {
currentExercice++;
}, 3000);
}}
{#if step === 0}
<div class="max-w-screen-md mx-auto p-20 flex flex-col items-center min-h-screen">
<h2 class="mb-10 text-xl text-center">{$t('tests.typing')}</h2>
<p class="mb-4 text-lg font-semibold">{$t('surveys.code')}</p>
<p class="mb-6 text-sm text-gray-600 text-center">{@html $t('surveys.codeIndication')}</p>
<input
type="text"
placeholder="Code"
class="input block mx-auto w-full max-w-xs border border-gray-300 rounded-md py-2 px-3 text-center"
onkeydown={(e) => e.key === 'Enter' && checkCode()}
bind:value={code}
/>
{/if}
{/each}
<div class="flex items-center mt-8">
{#if currentExercice < exercices.length - 1}
<button
class="button m-auto"
onclick={() => {
currentExercice++;
inProgress = false;
}}
disabled={inProgress}
class="button mt-4 block bg-yellow-500 text-white rounded-md py-2 px-6 hover:bg-yellow-600 transition"
onclick={checkCode}
>
{$t('button.next')}
</button>
{:else}
<button class="button m-auto" disabled={inProgress} onclick={submit}
>{$t('button.submit')}</button
>
{/if}
</div>
</div>
{:else if step <= exercices.length}
{@const j = step - 1}
{#each exercices as _, i (i)}
{#if i === j}
<Typingbox
exerciceId={i}
initialDuration={exercices[i].duration}
explications={exercices[i].explications}
text={exercices[i].text}
bind:data
bind:inProgress
onFinish={() => {
inProgress = false;
setTimeout(() => {
step++;
}, 3000);
}}
/>
{/if}
{/each}
{:else}
<div class="flex items-center mt-8">
<button class="button m-auto" disabled={inProgress} onclick={submit}>
{$t('button.submit')}
</button>
</div>
{/if}
......@@ -25,14 +25,12 @@
}
let step = $state(user ? 2 : 0);
let uuid = $state(user?.email || '');
let uid = $state(user?.id || null);
let code = $state('');
let subStep = $state(0);
let currentGroupId = $state(0);
survey.groups.sort((a, b) => {
//puts the demo questions first
if (a.demo === b.demo) {
return 0;
}
......@@ -216,7 +214,7 @@
<div class="max-w-screen-md mx-auto p-20 flex flex-col items-center min-h-screen">
<h2 class="mb-10 text-xl text-center">{survey.title}</h2>
<p class="mb-4 text-lg font-semibold">{$t('surveys.code')}</p>
<p class="mb-6 text-sm text-gray-600 text-center">{$t('surveys.codeIndication')}</p>
<p class="mb-6 text-sm text-gray-600 text-center">{@html $t('surveys.codeIndication')}</p>
<input
type="text"
placeholder="Code"
......@@ -256,7 +254,7 @@
{#if type == 'gap' && gaps}
<div class="mx-auto mt-16 center flex flex-col">
<div>
{#each gaps as part}
{#each gaps as part (part)}
{#if part.gap !== null}
<Gapfill length={part.text.length} onInput={(text) => (part.gap = text)} />
{:else}
......
import { redirect, type ServerLoad } from '@sveltejs/kit';
export const load: ServerLoad = async ({ params, locals }) => {
if (locals.user == null || locals.user == undefined) {
redirect(303, '/login?redirect=/tests/typing/' + params.id);
}
};
......@@ -5,7 +5,7 @@
let finished = $state(false);
let { data } = $props();
let user = data.user!;
let user = data.user;
</script>
{#if finished}
......
......@@ -8,4 +8,9 @@ id,title,demo,options
13,APVT-fr-0.1-27i-B1,false,1031,1032,1033,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060
14,APVT-fr-0.1-23i-B2,false,1061,1062,1063,1065,1066,1067,1068,1069,1071,1073,1076,1077,1078,1079,1080,1081,1083,1084,1085,1087,1088,1089
15,APVT-fr-0.1-15i-C1,false,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105
20,Vocabulary test sample,true,200
21,Vocabulary test base,false,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215
22,Vocabulary test T1,false,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230
23,Vocabulary test T2,false,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245
24,Vocabulary test T3,false,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260
1100,basic-survey-questions,false,
\ No newline at end of file
......@@ -78,6 +78,67 @@ id,question,correct,option1,option2,option3,option4,option5,option6,option7,opti
177,,1,,,,,,,,
178,,1,,,,,,,,
179,,1,,,,,,,,
200,"My flowers are beauti<ful>.",-1
201,"He has a successful car<eer> as a lawyer.",-1
202,"Sudden noises at night sca<re> me a lot and keep me awake.",-1
203,"Many people are inj<ured> in road accidents every year.",-1
204,"Don't pay attention to this rude remark. Just ign<ore> it.",-1
205,"There has been a recent tr<end> among prosperous families towards a smaller number of children.",-1
206,"He is irresponsible. You cannot re<ly> on him for help.",-1
207,"This work is not up to your usu<al> standard.",-1
208,"You must have been very br<ave> to participate in such a dangerous operation.",-1
209,"They sat down to eat even though they were not hu<ngry>.",-1
210,"You must be awa<re> that very few jobs are available.",-1
211,"The workmen cleaned up the me<ss> before they left.",-1
212,"The drug was introduced after medical res<earch> indisputably proved its effectiveness.",-1
213,"Governments often cut budgets in times of financial cri<sis>.",-1
214,"In a lecture, most of the talking is done by the lecturer. In a seminar, students are expected to part<icipate> in the discussion.",-1
215,"It's difficult to ass<ess> a person's true knowledge by one or two tests.",-1
216,"There are a doz<en> eggs in the basket.",-1
217,"The Far East is one of the most populated reg<ions> of the world.",-1
218,"She spent her childhood in Europe and most of her ad<ult> life in Asia.",-1
219,"La<ck> of rain led to a shortage of water in the city.",-1
220,"His new book will be pub<lished> at the end of this month by a famous University Press.",-1
221,"She didn't openly attack the plan, but her opposition was imp<licit> in her attitude.",-1
222,"This sweater is too tight. It needs to be stret<ched>.",-1
223,"In order to be accepted into the university, he had to impr<ove> his grades.",-1
224,"He had been expe<lled> from school for stealing.",-1
225,"Plants receive water from the soil though their ro<ots>.",-1
226,"The children's games were funny at first, but finally got on the parents' ner<ves>.",-1
227,"Before writing the final version, the student wrote several dra<fts>.",-1
228,"I've had my eyes tested and the optician says my vi<sion> is good.",-1
229,"In a free country, people can apply for any job. They should not be discriminated against on the basis of colour, age, or s<ex>.",-1
230,"His decision to leave home was not well thought out. It was not based on rat<ional> considerations.",-1
231,"They insp<ected> all products before sending them out to stores.",-1
232,"The challenging job required a young, successful and dyn<amic> candidate.",-1
233,"Even though I don't usually side with you, in this ins<tance> I must admit that you're right.",-1
234,"If I were you I would con<tact> a good lawyer before taking action.",-1
235,"The book covers a series of isolated epis<odes> from history.",-1
236,"She is not a child, but a mat<ure> woman. She can make her own decisions.",-1
237,"After finishing his degree, he entered upon a new ph<ase> in his career.",-1
238,"The airport is far away. If you want to ens<ure> that you catch your plane, you have to leave early.",-1
239,"The plaster on the wall was removed to exp<ose> the original bricks underneath.",-1
240,"Farmers are introducing innova<tions> that increase the productivity per worker.",-1
241,"A considerable amount of evidence was accum<ulated> during the investigation.",-1
242,"Since he is unskilled, he earns low wa<ges>.",-1
243,"Research ind<icates> that men find it easier to give up smoking than women.",-1
244,"It is not easy to abs<orb> all this information in such a short time.",-1
245,"People have proposed all kinds of hypot<heses> about what these things are.",-1
246,"The lack of money depressed and frust<rated> him.",-1
247,"The story tells us about a crime and sub<sequent> punishment.",-1
248,"It's impossible to eva<luate> these results without knowing about the research methods that were used.",-1
249,"I'm glad we had this opp<ortunity> to talk.",-1
250,"The differences were so sl<ight> that they went unnoticed.",-1
251,"To improve the country's economy, the government decided on economic ref<orms>.",-1
252,"Laws are based upon the principle of jus<tice>.",-1
253,"Anna intro<duced> her boyfriend to her mother last night.",-1
254,"The dress you're wearing is lov<ely>.",-1
255,"They had to cl<imb> a steep mountain to reach the cabin.",-1
256,"The doctor ex<amined> the patient thoroughly.",-1
257,"He takes cr<eam> and sugar in his coffee.",-1
258,"Every year, the organisers li<mit> the number of participants to fifty.",-1
259,"He usually reads the sport sec<tion> of the newspaper first.",-1
260,"Teenagers often adm<ire> and worship pop singers.",-1
1000,,1,,,,
1001,,1,,,,
1002,,1,,,,
......@@ -113,8 +174,6 @@ id,question,correct,option1,option2,option3,option4,option5,option6,option7,opti
1032,,1,,,,
1033,,1,,,,
1037,,1,,,,
1038,,1,,,,
1039,,1,,,,
......@@ -153,7 +212,6 @@ id,question,correct,option1,option2,option3,option4,option5,option6,option7,opti
1073,,1,,,,
1076,,1,,,,
1077,,1,,,,
1078,,1,,,,
......@@ -183,4 +241,4 @@ id,question,correct,option1,option2,option3,option4,option5,option6,option7,opti
1102,,1,,,,
1103,,1,,,,
1104,,1,,,,
1105,,1,,,,
1105,,1,,,,
\ No newline at end of file