diff --git a/backend/apps/web/routers/auths.py b/backend/apps/web/routers/auths.py index e4a41a74..ee275093 100644 --- a/backend/apps/web/routers/auths.py +++ b/backend/apps/web/routers/auths.py @@ -1,12 +1,14 @@ import logging -from fastapi import Request +from fastapi import Request, UploadFile, File from fastapi import Depends, HTTPException, status from fastapi import APIRouter from pydantic import BaseModel import re import uuid +import csv + from apps.web.models.auths import ( SigninForm, @@ -212,7 +214,7 @@ async def signup(request: Request, form_data: SignupForm): @router.post("/add", response_model=SigninResponse) -async def signup(form_data: AddUserForm, user=Depends(get_admin_user)): +async def add_user(form_data: AddUserForm, user=Depends(get_admin_user)): if not validate_email_format(form_data.email.lower()): raise HTTPException( @@ -251,6 +253,76 @@ async def signup(form_data: AddUserForm, user=Depends(get_admin_user)): raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) +@router.post("/add/import", response_model=SigninResponse) +async def add_user_csv_import( + file: UploadFile = File(...), user=Depends(get_admin_user) +): + try: + + # Check if the file is a CSV file + if file.filename.endswith(".csv"): + # Read the contents of the CSV file + contents = await file.read() + + # Decode the contents from bytes to string + decoded_content = contents.decode("utf-8") + + # Split the CSV content into lines + csv_lines = decoded_content.split("\n") + + # Parse CSV + csv_data = [] + csv_reader = csv.reader(csv_lines) + for row in csv_reader: + csv_data.append(row) + + # Print the CSV data + for row in csv_data: + print(row) + + return {"message": "CSV file uploaded successfully."} + else: + raise "File must be a CSV." + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + + # if not validate_email_format(form_data.email.lower()): + # raise HTTPException( + # status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT + # ) + + # if Users.get_user_by_email(form_data.email.lower()): + # raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + + # try: + + # print(form_data) + # hashed = get_password_hash(form_data.password) + # user = Auths.insert_new_auth( + # form_data.email.lower(), + # hashed, + # form_data.name, + # form_data.profile_image_url, + # form_data.role, + # ) + + # if user: + # token = create_token(data={"id": user.id}) + # return { + # "token": token, + # "token_type": "Bearer", + # "id": user.id, + # "email": user.email, + # "name": user.name, + # "role": user.role, + # "profile_image_url": user.profile_image_url, + # } + # else: + # raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + # except Exception as err: + # raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + + ############################ # ToggleSignUp ############################ diff --git a/backend/static/user-import.csv b/backend/static/user-import.csv new file mode 100644 index 00000000..918a92aa --- /dev/null +++ b/backend/static/user-import.csv @@ -0,0 +1 @@ +Name,Email,Password,Role diff --git a/src/lib/components/admin/AddUserModal.svelte b/src/lib/components/admin/AddUserModal.svelte index e779c9f7..85372eb7 100644 --- a/src/lib/components/admin/AddUserModal.svelte +++ b/src/lib/components/admin/AddUserModal.svelte @@ -5,12 +5,16 @@ import { addUser } from '$lib/apis/auths'; import Modal from '../common/Modal.svelte'; + import { WEBUI_BASE_URL } from '$lib/constants'; const i18n = getContext('i18n'); const dispatch = createEventDispatcher(); export let show = false; + let tab = ''; + let inputFiles; + let _user = { name: '', email: '', @@ -76,69 +80,126 @@ submitHandler(); }} > -
-
-
{$i18n.t('Role')}
+
+ -
- + +
+
+ {#if tab === ''} +
+
{$i18n.t('Role')}
+ +
+ +
-
-
-
{$i18n.t('Name')}
+
+
{$i18n.t('Name')}
-
- +
+ +
-
-
+
-
-
{$i18n.t('Email')}
+
+
{$i18n.t('Email')}
-
- +
+ +
-
-
-
{$i18n.t('Password')}
+
+
{$i18n.t('Password')}
-
- +
+ +
-
+ {:else if tab === 'import'} +
+
+ + + +
+ +
+ ⓘ {$i18n.t( + 'Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.' + )} + + Click here to download user import template file. + +
+
+ {/if}
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index a426307b..06361e3e 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -154,7 +154,7 @@ if (isCtrlPressed && event.key === '.') { event.preventDefault(); console.log('openSettings'); - document.getElementById('open-settings-button')?.click(); + showSettings.set(!$showSettings); } // Check if Ctrl + / is pressed