diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000000000000000000000000000000000000..05097f86d224a13060b9c0ae5ccb8cf67bbe85a9 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,15 @@ +#!/bin/sh + +git stash -q --keep-index + +cd frontend +npm run format +npm run lint +cd .. + +black backend +black --check backend + +git stash pop -q + +exit 0 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6227ab7451a9154374f518a9248a4e99f87ff8ac..0f8e3602d100b9d08452b851f08cd12243758a19 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,17 +1,30 @@ -default: - image: docker:latest - services: - - docker:dind - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - stages: + - lint - build +lint_frontend: + stage: lint + image: node + script: + - cd frontend + - npm install + - npm run lint + +lint_backend: + stage: lint + image: registry.gitlab.com/pipeline-components/black:latest + script: + - black --check --verbose -- . + build: stage: build only: - main + image: docker:latest + services: + - docker:dind + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY parallel: matrix: - COMPONENT: [frontend, backend] diff --git a/backend/app/database.py b/backend/app/database.py index 79b9f0f0f87f3657c1f8da1d5dca84d9c813704a..3536ec2ae76bba80bab981b2385bd9d64e3ad0f0 100644 --- a/backend/app/database.py +++ b/backend/app/database.py @@ -17,4 +17,3 @@ def get_db(): yield db finally: db.close() - diff --git a/backend/app/hashing.py b/backend/app/hashing.py index 45969d83d521ecadb58f304d7b9a10a889be9cc8..760471471af379ea1d2b93009c5c7e1415d64b84 100644 --- a/backend/app/hashing.py +++ b/backend/app/hashing.py @@ -15,18 +15,12 @@ import crud pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") -reuseable_oauth = OAuth2PasswordBearer( - tokenUrl="/login", - scheme_name="JWT" -) +reuseable_oauth = OAuth2PasswordBearer(tokenUrl="/login", scheme_name="JWT") -reuseable_refresh_oauth = OAuth2PasswordBearer( - tokenUrl="/refresh", - scheme_name="JWT" -) +reuseable_refresh_oauth = OAuth2PasswordBearer(tokenUrl="/refresh", scheme_name="JWT") -class Hasher(): +class Hasher: @staticmethod def verify_password(plain_password, hashed_password): return pwd_context.verify(plain_password, hashed_password) @@ -40,13 +34,22 @@ def create_access_token(user: models.User, expires_delta: int = -1) -> str: if expires_delta > 0: expires_delta = int(datetime.now(UTC).timestamp()) + expires_delta else: - expires_delta = int((datetime.now( - UTC) + timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES)).timestamp()) - - to_encode = {"exp": expires_delta, "sub": str( - user.id), "type": user.type, "email": user.email, "nickname": user.nickname, "is_active": user.is_active} - encoded_jwt = jwt.encode( - to_encode, config.JWT_SECRET_KEY, config.ALGORITHM) + expires_delta = int( + ( + datetime.now(UTC) + + timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES) + ).timestamp() + ) + + to_encode = { + "exp": expires_delta, + "sub": str(user.id), + "type": user.type, + "email": user.email, + "nickname": user.nickname, + "is_active": user.is_active, + } + encoded_jwt = jwt.encode(to_encode, config.JWT_SECRET_KEY, config.ALGORITHM) return encoded_jwt @@ -54,20 +57,30 @@ def create_refresh_token(user: models.User, expires_delta: int = -1) -> str: if expires_delta > 0: expires_delta = int(datetime.now(UTC).timestamp()) + expires_delta else: - expires_delta = int((datetime.now( - UTC) + timedelta(minutes=config.REFRESH_TOKEN_EXPIRE_MINUTES)).timestamp()) - - to_encode = {"exp": expires_delta, "sub": str( - user.id), "type": user.type, "email": user.email, "nickname": user.nickname, "is_active": user.is_active} - encoded_jwt = jwt.encode( - to_encode, config.JWT_REFRESH_SECRET_KEY, config.ALGORITHM) + expires_delta = int( + ( + datetime.now(UTC) + + timedelta(minutes=config.REFRESH_TOKEN_EXPIRE_MINUTES) + ).timestamp() + ) + + to_encode = { + "exp": expires_delta, + "sub": str(user.id), + "type": user.type, + "email": user.email, + "nickname": user.nickname, + "is_active": user.is_active, + } + encoded_jwt = jwt.encode(to_encode, config.JWT_REFRESH_SECRET_KEY, config.ALGORITHM) return encoded_jwt def get_jwt_user(token: str = Depends(reuseable_oauth), db: Session = Depends(get_db)): try: - payload = jwt.decode(token, config.JWT_SECRET_KEY, - algorithms=[config.ALGORITHM]) + payload = jwt.decode( + token, config.JWT_SECRET_KEY, algorithms=[config.ALGORITHM] + ) token_data = schemas.TokenPayload(**payload) if token_data.exp is None or token_data.sub is None: @@ -81,12 +94,19 @@ def get_jwt_user(token: str = Depends(reuseable_oauth), db: Session = Depends(ge except jwte.ExpiredSignatureError: raise HTTPException(status_code=401, detail="Token has expired") - except (jwte.JWTError, jwte.ExpiredSignatureError, ValidationError, ValueError) as e: + except ( + jwte.JWTError, + jwte.ExpiredSignatureError, + ValidationError, + ValueError, + ) as e: print(e) raise HTTPException(status_code=403, detail="Invalid token") return db_user -def get_jwt_user_from_refresh_token(token: str = Depends(reuseable_refresh_oauth), db: Session = Depends(get_db)): +def get_jwt_user_from_refresh_token( + token: str = Depends(reuseable_refresh_oauth), db: Session = Depends(get_db) +): return get_jwt_user(token, db) diff --git a/backend/app/main.py b/backend/app/main.py index 5dd053f1febb4be45708f75dded45803c938c8ef..0071d39163de31d7e7f0510b724e1efd01df255e 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -121,7 +121,12 @@ def register( if db_user: raise HTTPException(status_code=400, detail="User already registered") - user_data = schemas.UserCreate(email=email, password=password, nickname=nickname, type=models.UserType.TUTOR.value if tutor else models.UserType.STUDENT.value) + user_data = schemas.UserCreate( + email=email, + password=password, + nickname=nickname, + type=models.UserType.TUTOR.value if tutor else models.UserType.STUDENT.value, + ) user = crud.create_user(db=db, user=user_data) @@ -399,32 +404,38 @@ def create_weekly_survey( db_user = crud.get_user(db, user_id) if db_user is None: raise HTTPException(status_code=404, detail="User not found") - + return crud.create_user_survey_weekly(db, user_id, survey).id -@usersRouter.post('/{user_id}/contacts/{contact_id}/bookings', status_code=status.HTTP_201_CREATED) + +@usersRouter.post( + "/{user_id}/contacts/{contact_id}/bookings", status_code=status.HTTP_201_CREATED +) def create_booking( - user_id: int, - contact_id: int, - booking: schemas.SessionBookingCreate, - 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 booking 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") - db_contact = crud.get_user(db, contact_id) - if db_contact is None: - raise HTTPException(status_code=404, detail="Contact not found") - return crud.create_session_with_users(db, [db_user, db_contact], booking.start_time, booking.end_time).id + user_id: int, + contact_id: int, + booking: schemas.SessionBookingCreate, + 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 booking 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") + db_contact = crud.get_user(db, contact_id) + if db_contact is None: + raise HTTPException(status_code=404, detail="Contact not found") + return crud.create_session_with_users( + db, [db_user, db_contact], booking.start_time, booking.end_time + ).id + @sessionsRouter.post("", response_model=schemas.Session) def create_session( @@ -495,6 +506,7 @@ def update_session( crud.update_session(db, session, session_id) + @sessionsRouter.get("/{session_id}/download/messages") def download_session( session_id: int, @@ -507,7 +519,8 @@ def download_session( if not check_user_level(current_user, models.UserType.ADMIN): raise HTTPException( - status_code=401, detail="You do not have permission to download this session" + status_code=401, + detail="You do not have permission to download this session", ) data = crud.get_messages(db, session_id) @@ -521,7 +534,13 @@ def download_session( output.seek(0) - return StreamingResponse(output, media_type="text/csv", headers={"Content-Disposition": f"attachment; filename={session_id}-messages.csv"}) + return StreamingResponse( + output, + media_type="text/csv", + headers={ + "Content-Disposition": f"attachment; filename={session_id}-messages.csv" + }, + ) @sessionsRouter.post( @@ -792,6 +811,7 @@ def propagate_presence( return + @studyRouter.post("/", status_code=status.HTTP_201_CREATED) def study_create( study: schemas.StudyCreate, @@ -804,6 +824,7 @@ def study_create( ) return crud.create_study(db, study).id + @websocketRouter.websocket("/sessions/{session_id}") async def websocket_session( session_id: int, @@ -1154,6 +1175,7 @@ def get_survey_responses( return crud.get_survey_responses(db, survey_id) + v1Router.include_router(authRouter) v1Router.include_router(usersRouter) v1Router.include_router(sessionsRouter) diff --git a/backend/app/test_main.py b/backend/app/test_main.py index 90ac9fabf04fa1110d3cb5ff6fadcbb3e609c9da..dc5a19d6060b60bbe4a08aa65da4a85d85668f45 100644 --- a/backend/app/test_main.py +++ b/backend/app/test_main.py @@ -15,9 +15,7 @@ def test_read_main(): def test_webhook_create(): response = client.post( "/api/v1/webhooks/sessions", - headers={ - "X-Cal-Signature-256": config.CALCOM_SECRET - }, + headers={"X-Cal-Signature-256": config.CALCOM_SECRET}, json={ "triggerEvent": "BOOKING_CREATED", "createdAt": "2023-05-24T09:30:00.538Z", @@ -27,44 +25,34 @@ def test_webhook_create(): "description": "", "additionalNotes": "", "customInputs": {}, - "startTime": (datetime.datetime.now() + datetime.timedelta(days=1, hours=1)).isoformat(), - "endTime": (datetime.datetime.now() + datetime.timedelta(days=1, hours=2)).isoformat(), + "startTime": ( + datetime.datetime.now() + datetime.timedelta(days=1, hours=1) + ).isoformat(), + "endTime": ( + datetime.datetime.now() + datetime.timedelta(days=1, hours=2) + ).isoformat(), "organizer": { "id": 5, "name": "Pro Example", "email": "pro@example.com", "username": "pro", "timeZone": "Asia/Kolkata", - "language": { - "locale": "en" - }, - "timeFormat": "h:mma" + "language": {"locale": "en"}, + "timeFormat": "h:mma", }, "responses": { - "name": { - "label": "your_name", - "value": "John Doe" - }, + "name": {"label": "your_name", "value": "John Doe"}, "email": { "label": "email_address", - "value": "john.doe@example.com" + "value": "john.doe@example.com", }, "location": { "label": "location", - "value": { - "optionValue": "", - "value": "inPerson" - } - }, - "notes": { - "label": "additional_notes" + "value": {"optionValue": "", "value": "inPerson"}, }, - "guests": { - "label": "additional_guests" - }, - "rescheduleReason": { - "label": "reschedule_reason" - } + "notes": {"label": "additional_notes"}, + "guests": {"label": "additional_guests"}, + "rescheduleReason": {"label": "reschedule_reason"}, }, "userFieldsResponses": {}, "attendees": [ @@ -72,9 +60,7 @@ def test_webhook_create(): "email": "admin@admin.tld", "name": "John Doe", "timeZone": "Asia/Kolkata", - "language": { - "locale": "en" - } + "language": {"locale": "en"}, } ], "location": "Calcom HQ", @@ -84,7 +70,7 @@ def test_webhook_create(): "externalId": "https://caldav.icloud.com/1234567/calendars/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/", "userId": 5, "eventTypeId": None, - "credentialId": 1 + "credentialId": 1, }, "hideCalendarNotes": False, "requiresConfirmation": None, @@ -99,7 +85,7 @@ def test_webhook_create(): "success": 1, "failures": 0, "errors": [], - "warnings": [] + "warnings": [], } ], "eventTitle": "60min", @@ -109,10 +95,12 @@ def test_webhook_create(): "length": 60, "bookingId": 91, "metadata": {}, - "status": "ACCEPTED" - } - } + "status": "ACCEPTED", + }, + }, ) - assert response.status_code == 202, (response.status_code, - response.content.decode("utf-8")) + assert response.status_code == 202, ( + response.status_code, + response.content.decode("utf-8"), + ) diff --git a/frontend/.prettierignore b/frontend/.prettierignore index cc41cea9b2673a41363c39cacdf91b63df4e8ba0..5c95eabf3e305e89df51527f40ce349578ebb46b 100644 --- a/frontend/.prettierignore +++ b/frontend/.prettierignore @@ -2,3 +2,4 @@ pnpm-lock.yaml package-lock.json yarn.lock +static/ diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 10e0d52638b6598c07ef938cdc0dfb2609cbe8d2..eea21621e7b76784da24491fdbfa0b8b414470a3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2428,18 +2428,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", diff --git a/frontend/package.json b/frontend/package.json index d51f1c91ecf4c9b2fdca7d704cf123b5295d19a0..db37ad4f6e9ff0f8c4974e54b478825874de0398 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,8 +7,8 @@ "build": "vite build", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "prettier --check . && eslint .", - "format": "prettier --write ." + "lint": "prettier --check .", + "format": "prettier --write . --log-level warn" }, "devDependencies": { "@rollup/plugin-json": "^6.1.0", diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js index 2e7af2b7f1a6f391da1631d93968a9d487ba977d..0f7721681d725ddea512a5ed734891cf6545ca3c 100644 --- a/frontend/postcss.config.js +++ b/frontend/postcss.config.js @@ -1,6 +1,6 @@ export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/frontend/rollup.config.js b/frontend/rollup.config.js index 983b1302e55979e3ee09ca7b8e33ca1efde08f7c..4c0caa2b0d15d972d44652a9688793fd3b8bbd91 100644 --- a/frontend/rollup.config.js +++ b/frontend/rollup.config.js @@ -1,4 +1,5 @@ import json from '@rollup/plugin-json'; +import svelte from 'rollup-plugin-svelte'; export default { plugins: [json(), svelte({})] diff --git a/frontend/src/lib/api/apiInstance.ts b/frontend/src/lib/api/apiInstance.ts index 50c4f3467e930c2104fea0ccc0c15c109556170b..2053a846812acc86bf5554e370cba59dd07e97ce 100644 --- a/frontend/src/lib/api/apiInstance.ts +++ b/frontend/src/lib/api/apiInstance.ts @@ -2,7 +2,7 @@ import axios from 'axios'; import config from '$lib/config'; import { writable, get } from 'svelte/store'; -export let access_cookie = writable(''); +export const access_cookie = writable(''); export const axiosPublicInstance = axios.create({ ...axios.defaults, diff --git a/frontend/src/lib/api/sessions.ts b/frontend/src/lib/api/sessions.ts index 31e47b1fd6a86547cec34ee35e11fc6074b35f69..00078a5d99306e5d2b4a7465099594e0ef1e9c8d 100644 --- a/frontend/src/lib/api/sessions.ts +++ b/frontend/src/lib/api/sessions.ts @@ -45,7 +45,7 @@ export async function createMessageAPI( id: number, content: string, metadata: { message: string; date: number }[] -): Promise<any | null> { +): Promise<number | null> { const response = await axiosInstance.post(`/sessions/${id}/messages`, { content, metadata }); if (response.status !== 201) { @@ -61,7 +61,7 @@ export async function updateMessageAPI( message_id: string, content: string, metadata: { message: string; date: number }[] -): Promise<any | null> { +): Promise<number | null> { const response = await axiosInstance.post(`/sessions/${id}/messages`, { message_id, content, diff --git a/frontend/src/lib/api/tests.ts b/frontend/src/lib/api/tests.ts index 043e832ebe667fa835c8db31c034faf1fde609b9..f95de8df0bb4e3569162c8a4e72233d332972a5d 100644 --- a/frontend/src/lib/api/tests.ts +++ b/frontend/src/lib/api/tests.ts @@ -1,5 +1,6 @@ import { axiosInstance } from './apiInstance'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export async function sendTestVocabularyAPI(data: any): Promise<boolean> { const response = await axiosInstance.post(`/tests/vocabulary`, { content: data }); diff --git a/frontend/src/lib/api/users.ts b/frontend/src/lib/api/users.ts index b5d3ced3e99aa115de2c78f361502e56786d0b04..0d6a1bbc3a9bd705cb2f71896518e8bcab527329 100644 --- a/frontend/src/lib/api/users.ts +++ b/frontend/src/lib/api/users.ts @@ -113,6 +113,7 @@ export async function createUserAPI( return response.data; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export async function patchUserAPI(user_id: number, data: any): Promise<boolean> { try { const response = await axiosInstance.patch(`/users/${user_id}`, data); diff --git a/frontend/src/lib/components/header.svelte b/frontend/src/lib/components/header.svelte index 3f320e1f3a04e434c6237bd64a4ec145a2505603..6f8db00fa5e12bd1f0960983a65c6ebef0710648 100644 --- a/frontend/src/lib/components/header.svelte +++ b/frontend/src/lib/components/header.svelte @@ -31,7 +31,7 @@ <Icon src={Bars3} class="h-5 w-5" /> </div> <ul - tabindex="0" + tabindex="-1" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52" > {#if $user} @@ -46,7 +46,7 @@ <li><a href="/">Item 3</a></li> {/if} <li> - <a>{$t('header.language')}</a> + <span>{$t('header.language')}</span> <ul class="p-2"> <LocalSelector /> </ul> diff --git a/frontend/src/lib/components/header/localSelector.svelte b/frontend/src/lib/components/header/localSelector.svelte index e0873d08785d90942e2e4984d9b44d428b3c080a..ed5fe0cff4e1a5877bf82467dd89a3308e65288e 100644 --- a/frontend/src/lib/components/header/localSelector.svelte +++ b/frontend/src/lib/components/header/localSelector.svelte @@ -1,10 +1,7 @@ <script lang="ts"> - import { locale, locales, t } from '$lib/services/i18n'; + import { locale, locales } from '$lib/services/i18n'; import { get } from 'svelte/store'; - let classes = ''; - export { classes as class }; - function onChange(value: string) { if (value !== get(locale)) { // TODO: Should be in place @@ -18,4 +15,4 @@ {#each $locales as name (name)} <li><button on:click={() => onChange(name)}>{name}</button></li> {/each} -<!-- </ul> --> \ No newline at end of file +<!-- </ul> --> diff --git a/frontend/src/lib/components/sessions/editParticipants.svelte b/frontend/src/lib/components/sessions/editParticipants.svelte index 8d561f273a5af3940d36912fa7239f5d8f694e06..e8776f1dcc723dff13456bdce56c8fa7e5089713 100644 --- a/frontend/src/lib/components/sessions/editParticipants.svelte +++ b/frontend/src/lib/components/sessions/editParticipants.svelte @@ -5,7 +5,7 @@ import Select from 'svelte-select'; import { get } from 'svelte/store'; import { onMount } from 'svelte'; - import { Icon, Language, XMark } from 'svelte-hero-icons'; + import { Icon, XMark } from 'svelte-hero-icons'; import { t } from '$lib/services/i18n'; import config from '$lib/config'; diff --git a/frontend/src/lib/components/sessions/message.svelte b/frontend/src/lib/components/sessions/message.svelte index 51708dc8f9f1b22261afd2dce8956b4b113eafb4..1e6c6e94d330c31d87d27c1b32cbe6f30080f5af 100644 --- a/frontend/src/lib/components/sessions/message.svelte +++ b/frontend/src/lib/components/sessions/message.svelte @@ -195,6 +195,7 @@ > {/if} {:else} + <!-- eslint-disable-next-line svelte/no-at-html-tags --> {@html linkifyHtml(sanitize(part.text), { className: 'underline', target: '_blank' })} {/if} {/each} diff --git a/frontend/src/lib/components/sessions/writebox.svelte b/frontend/src/lib/components/sessions/writebox.svelte index 4061378688db62a55a59e92ab705de674e4fc56e..280fbf124d2a5a04cbdef37e7754c96a59b760d8 100644 --- a/frontend/src/lib/components/sessions/writebox.svelte +++ b/frontend/src/lib/components/sessions/writebox.svelte @@ -80,7 +80,7 @@ placeholder={disabled ? $t('chatbox.disabled') : $t('chatbox.placeholder')} {disabled} bind:value={message} - on:keypress={(e) => keyPress()} + on:keypress={() => keyPress()} on:keypress={async (e) => { if (e.key === 'Enter' && !e.shiftKey) { await sendMessage(); diff --git a/frontend/src/lib/components/surveys/gapfill.svelte b/frontend/src/lib/components/surveys/gapfill.svelte index be1cffaafd8b905448e1ae8ca68ca2cd03306e4d..5dbe48ecf0200563efc9224fce85eac2af8358b5 100644 --- a/frontend/src/lib/components/surveys/gapfill.svelte +++ b/frontend/src/lib/components/surveys/gapfill.svelte @@ -11,8 +11,7 @@ bind:value={content} on:input={(event) => onInput(event.target.value)} maxlength={length} - /><!-- - -->{#each Array.from({ length }) as _, i} + /><!-- -->{#each Array.from({ length }) as _, i} <label>{content[i] || '_'}</label> {/each} </span> diff --git a/frontend/src/lib/types/surveyQuestion.ts b/frontend/src/lib/types/surveyQuestion.ts index eb85c8ca384b8bda414bb79f0f4c2c4683892298..51e1e83db89c7392beb3549200df5bf8b1697820 100644 --- a/frontend/src/lib/types/surveyQuestion.ts +++ b/frontend/src/lib/types/surveyQuestion.ts @@ -35,7 +35,7 @@ export default class SurveyQuestion { return null; } - let options = []; + const options = []; if (data.option1) options.push(data.option1); if (data.option2) options.push(data.option2); if (data.option3) options.push(data.option3); diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index d83fe74913c38fc69e74d1424267a719dd15c218..a7c90acd7077955dfa01f2d16d89d3691062ec50 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -8,6 +8,8 @@ export let data; User.parseFromServer(data); + + console.log(2); </script> <svelte:head> diff --git a/frontend/src/routes/login/+page.svelte b/frontend/src/routes/login/+page.svelte index 3acabede65dbb85562e22711f13f26f5874973c6..ea3e8952e443644da761d83ebb5961ab01ec9909 100644 --- a/frontend/src/routes/login/+page.svelte +++ b/frontend/src/routes/login/+page.svelte @@ -23,7 +23,7 @@ } </script> -<div class="flex justify-center items-center h-screen"> +<div class="flex justify-center items-center h-screen"> <div class="flex flex-col w-full max-w-md rounded-box shadow-xl bg-base-200 gap-4 p-6"> <h1 class="text-3xl font-bold self-center">{$t('login.title')}</h1> @@ -53,7 +53,14 @@ <span class="label-text">{$t('login.email')}</span> </div> - <input type="text" id="email" name="email" class="input input-bordered" bind:value={email} required /> + <input + type="text" + id="email" + name="email" + class="input input-bordered" + bind:value={email} + required + /> </label> <label class="form-control"> @@ -63,7 +70,14 @@ <a class="label-text link link-secondary">{$t('login.forgotPassword')}</a> --> </div> - <input type="password" id="password" name="password" class="input input-bordered" bind:value={password} required /> + <input + type="password" + id="password" + name="password" + class="input input-bordered" + bind:value={password} + required + /> </label> <!-- <div class="form-control"> diff --git a/frontend/static/site.webmanifest b/frontend/static/site.webmanifest index 45dc8a20658bd09ecb8ca1c88f94fe80cc4ca286..52a2fe3f611fac18eb6a32e541065eabdccfb146 100755 --- a/frontend/static/site.webmanifest +++ b/frontend/static/site.webmanifest @@ -1 +1,11 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "", + "short_name": "", + "icons": [ + { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, + { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +}