mirror of
https://github.com/Mintplex-Labs/anything-llm
synced 2026-04-25 17:15:37 +02:00
Add bio field to user (#3346)
* add bio to users table * lint * add bio field to edit user admin page * fix bio saving on new user * simplify updating localstorage user * linting --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
@@ -50,9 +50,9 @@ export default function AccountModal({ user, hideModal }) {
|
||||
const { success, error } = await System.updateUser(data);
|
||||
if (success) {
|
||||
let storedUser = JSON.parse(localStorage.getItem(AUTH_USER));
|
||||
|
||||
if (storedUser) {
|
||||
storedUser.username = data.username;
|
||||
storedUser.bio = data.bio;
|
||||
localStorage.setItem(AUTH_USER, JSON.stringify(storedUser));
|
||||
}
|
||||
showToast("Profile updated.", "success", { clear: true });
|
||||
@@ -164,6 +164,20 @@ export default function AccountModal({ user, hideModal }) {
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="bio"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
>
|
||||
Bio
|
||||
</label>
|
||||
<textarea
|
||||
name="bio"
|
||||
className="border-none bg-theme-settings-input-bg placeholder:text-theme-settings-input-placeholder border-gray-500 text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5 min-h-[100px] resize-y"
|
||||
placeholder="Tell us about yourself..."
|
||||
defaultValue={user.bio}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-x-8">
|
||||
<ThemePreference />
|
||||
<LanguagePreference />
|
||||
|
||||
@@ -95,6 +95,21 @@ export default function NewUserModal({ closeModal }) {
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="bio"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
>
|
||||
Bio
|
||||
</label>
|
||||
<textarea
|
||||
name="bio"
|
||||
className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="User's bio"
|
||||
autoComplete="off"
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="role"
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
||||
import { X } from "@phosphor-icons/react";
|
||||
import Admin from "@/models/admin";
|
||||
import { MessageLimitInput, RoleHintDisplay } from "../..";
|
||||
import { AUTH_USER } from "@/utils/constants";
|
||||
|
||||
export default function EditUserModal({ currentUser, user, closeModal }) {
|
||||
const [role, setRole] = useState(user.role);
|
||||
@@ -27,7 +28,17 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
|
||||
}
|
||||
|
||||
const { success, error } = await Admin.updateUser(user.id, data);
|
||||
if (success) window.location.reload();
|
||||
if (success) {
|
||||
// Update local storage if we're editing our own user
|
||||
if (currentUser && currentUser.id === user.id) {
|
||||
currentUser.username = data.username;
|
||||
currentUser.bio = data.bio;
|
||||
currentUser.role = data.role;
|
||||
localStorage.setItem(AUTH_USER, JSON.stringify(currentUser));
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
setError(error);
|
||||
};
|
||||
|
||||
@@ -92,6 +103,22 @@ export default function EditUserModal({ currentUser, user, closeModal }) {
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="bio"
|
||||
className="block mb-2 text-sm font-medium text-white"
|
||||
>
|
||||
Bio
|
||||
</label>
|
||||
<textarea
|
||||
name="bio"
|
||||
className="border-none bg-theme-settings-input-bg w-full text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
|
||||
placeholder="User's bio"
|
||||
defaultValue={user.bio}
|
||||
autoComplete="off"
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label
|
||||
htmlFor="role"
|
||||
|
||||
@@ -1089,7 +1089,7 @@ function systemEndpoints(app) {
|
||||
app.post("/system/user", [validatedRequest], async (request, response) => {
|
||||
try {
|
||||
const sessionUser = await userFromSession(request, response);
|
||||
const { username, password } = reqBody(request);
|
||||
const { username, password, bio } = reqBody(request);
|
||||
const id = Number(sessionUser.id);
|
||||
|
||||
if (!id) {
|
||||
@@ -1098,12 +1098,10 @@ function systemEndpoints(app) {
|
||||
}
|
||||
|
||||
const updates = {};
|
||||
if (username) {
|
||||
if (username)
|
||||
updates.username = User.validations.username(String(username));
|
||||
}
|
||||
if (password) {
|
||||
updates.password = String(password);
|
||||
}
|
||||
if (password) updates.password = String(password);
|
||||
if (bio) updates.bio = String(bio);
|
||||
|
||||
if (Object.keys(updates).length === 0) {
|
||||
response
|
||||
|
||||
@@ -22,6 +22,7 @@ const User = {
|
||||
"role",
|
||||
"suspended",
|
||||
"dailyMessageLimit",
|
||||
"bio",
|
||||
],
|
||||
validations: {
|
||||
username: (newValue = "") => {
|
||||
@@ -54,6 +55,12 @@ const User = {
|
||||
}
|
||||
return limit;
|
||||
},
|
||||
bio: (bio = "") => {
|
||||
if (!bio || typeof bio !== "string") return "";
|
||||
if (bio.length > 1000)
|
||||
throw new Error("Bio cannot be longer than 1,000 characters");
|
||||
return String(bio);
|
||||
},
|
||||
},
|
||||
// validations for the above writable fields.
|
||||
castColumnValue: function (key, value) {
|
||||
@@ -77,6 +84,7 @@ const User = {
|
||||
password,
|
||||
role = "default",
|
||||
dailyMessageLimit = null,
|
||||
bio = "",
|
||||
}) {
|
||||
const passwordCheck = this.checkPasswordComplexity(password);
|
||||
if (!passwordCheck.checkedOK) {
|
||||
@@ -97,6 +105,7 @@ const User = {
|
||||
username: this.validations.username(username),
|
||||
password: hashedPassword,
|
||||
role: this.validations.role(role),
|
||||
bio: this.validations.bio(bio),
|
||||
dailyMessageLimit:
|
||||
this.validations.dailyMessageLimit(dailyMessageLimit),
|
||||
},
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "users" ADD COLUMN "bio" TEXT DEFAULT '';
|
||||
@@ -68,6 +68,7 @@ model users {
|
||||
createdAt DateTime @default(now())
|
||||
lastUpdatedAt DateTime @default(now())
|
||||
dailyMessageLimit Int?
|
||||
bio String? @default("")
|
||||
workspace_chats workspace_chats[]
|
||||
workspace_users workspace_users[]
|
||||
embed_configs embed_configs[]
|
||||
|
||||
Reference in New Issue
Block a user