upd
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useMask } from "@react-input/mask";
|
||||
|
||||
import { useState } from "react";
|
||||
interface InputProps {
|
||||
type?: "text" | "email" | "password" | "time" | "tel" | "number";
|
||||
value?: string;
|
||||
@@ -10,8 +10,10 @@ interface InputProps {
|
||||
readOnly?: boolean;
|
||||
className?: string;
|
||||
autoComplete?: string;
|
||||
handleChange?: (value: string) => void;
|
||||
handleFocus?: () => void;
|
||||
lowercase?: boolean;
|
||||
trim?: boolean;
|
||||
onChange?: (value: string) => void;
|
||||
onFocus?: () => void;
|
||||
}
|
||||
|
||||
function Input({
|
||||
@@ -23,14 +25,33 @@ function Input({
|
||||
readOnly,
|
||||
className,
|
||||
autoComplete,
|
||||
handleChange,
|
||||
handleFocus,
|
||||
onChange,
|
||||
onFocus,
|
||||
lowercase,
|
||||
trim,
|
||||
}: InputProps) {
|
||||
const [_value, setValue] = useState(value);
|
||||
|
||||
const inputRef = useMask({
|
||||
mask: "+7 (___) ___-__-__",
|
||||
replacement: { _: /\d/ },
|
||||
});
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
let value = e.target.value;
|
||||
|
||||
if (lowercase) {
|
||||
value = value.toLowerCase();
|
||||
}
|
||||
|
||||
if (trim) {
|
||||
value = value.trim();
|
||||
}
|
||||
|
||||
setValue(value);
|
||||
onChange?.(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<input
|
||||
autoComplete={autoComplete}
|
||||
@@ -40,9 +61,9 @@ function Input({
|
||||
autoFocus={autoFocus}
|
||||
required={required}
|
||||
readOnly={readOnly}
|
||||
value={value}
|
||||
onChange={(e) => handleChange && handleChange(e.target.value)}
|
||||
onFocus={handleFocus}
|
||||
value={_value}
|
||||
onChange={handleChange}
|
||||
onFocus={onFocus}
|
||||
className={`px-3 py-[9px] outline-none rounded-lg ring-1 ring-[#DAE0E5] focus:ring-[#49A1F5] ring-inset transition-all text-sm ${className}`}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -318,7 +318,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
<Input
|
||||
type="time"
|
||||
value={startTime}
|
||||
handleChange={(value) => setStartTime(value)}
|
||||
onChange={(value) => setStartTime(value)}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -328,7 +328,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
<Input
|
||||
type="time"
|
||||
value={endTime}
|
||||
handleChange={(value) => setEndTime(value)}
|
||||
onChange={(value) => setEndTime(value)}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -344,10 +344,12 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
<div className="space-y-1">
|
||||
<Label value="Email" />
|
||||
<Input
|
||||
lowercase
|
||||
trim
|
||||
type="email"
|
||||
className="w-full h-10"
|
||||
value={email}
|
||||
handleChange={(value) => setEmail(value)}
|
||||
onChange={(value) => setEmail(value)}
|
||||
/>
|
||||
<span className="text-[#77828C] text-xs">
|
||||
На указанный почтовый адрес придет необходимая для
|
||||
@@ -360,7 +362,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
type="tel"
|
||||
className="w-full h-10"
|
||||
value={phone}
|
||||
handleChange={(value) => setPhone(value)}
|
||||
onChange={(value) => setPhone(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
@@ -368,7 +370,7 @@ function Schedule({ selectedDay, slots, events }: Props) {
|
||||
<Input
|
||||
className="w-full h-10"
|
||||
value={name}
|
||||
handleChange={(value) => setName(value)}
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@ function Select({ defaultValue, options, handleChange }: SelectProps) {
|
||||
<div ref={selectRef} className="relative">
|
||||
<Input
|
||||
readOnly
|
||||
handleFocus={() => setIsShow(true)}
|
||||
onFocus={() => setIsShow(true)}
|
||||
value={options?.find((option) => option.value === value).text}
|
||||
className="w-full cursor-pointer"
|
||||
/>
|
||||
|
||||
@@ -107,21 +107,23 @@ function AddManagerModal() {
|
||||
<div className="space-y-1">
|
||||
<Label value="Email*" />
|
||||
<Input
|
||||
required
|
||||
autoFocus
|
||||
lowercase
|
||||
trim
|
||||
type="email"
|
||||
className="w-full"
|
||||
autoFocus
|
||||
required
|
||||
value={username}
|
||||
handleChange={(value) => setUsername(value)}
|
||||
onChange={(value) => setUsername(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label value="Имя*" />
|
||||
<Input
|
||||
className="w-full"
|
||||
required
|
||||
className="w-full"
|
||||
value={name}
|
||||
handleChange={(value) => setName(value)}
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
|
||||
@@ -146,7 +146,7 @@ function CompanyModal() {
|
||||
<Input
|
||||
type="time"
|
||||
value={startTime}
|
||||
handleChange={(value) => setStartTime(value)}
|
||||
onChange={(value) => setStartTime(value)}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-[#77828C] mt-4">-</p>
|
||||
@@ -155,7 +155,7 @@ function CompanyModal() {
|
||||
<Input
|
||||
type="time"
|
||||
value={endTime}
|
||||
handleChange={(value) => setEndTime(value)}
|
||||
onChange={(value) => setEndTime(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -50,13 +50,14 @@ function CreateBuildModal({ companyId }: Props) {
|
||||
<p className="text-xl font-semibold">Создание ЖК</p>
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<Input
|
||||
required
|
||||
autoFocus
|
||||
placeholder="Название ЖК"
|
||||
className="w-64"
|
||||
handleChange={(value) => setName(value)}
|
||||
autoFocus
|
||||
required
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
<Select3
|
||||
required
|
||||
options={[
|
||||
"nksJukovaDev",
|
||||
"Avgust",
|
||||
@@ -89,7 +90,6 @@ function CreateBuildModal({ companyId }: Props) {
|
||||
"Zoolog",
|
||||
]}
|
||||
onSelect={(option) => setBuild(option)}
|
||||
required
|
||||
/>
|
||||
<div className="flex self-end gap-2">
|
||||
<Button variant="secondary" onClick={() => setModal(null)}>
|
||||
|
||||
@@ -44,19 +44,19 @@ function CreateCompanyModal() {
|
||||
<p className="text-xl font-semibold">Создание компании</p>
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<Input
|
||||
required
|
||||
autoFocus
|
||||
placeholder="Название компании"
|
||||
className="w-64"
|
||||
handleChange={(value) => setName(value)}
|
||||
autoFocus
|
||||
required
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
<Input
|
||||
required
|
||||
type="number"
|
||||
placeholder="Кол-во серверов"
|
||||
className="w-64"
|
||||
type="number"
|
||||
required
|
||||
value={sessionLimit?.toString()}
|
||||
handleChange={(value) => setSessionLimit(+value)}
|
||||
onChange={(value) => setSessionLimit(+value)}
|
||||
/>
|
||||
<div className="flex self-end gap-2">
|
||||
<Button variant="secondary" onClick={() => setModal(null)}>
|
||||
|
||||
@@ -160,7 +160,7 @@ function CreateScheduleModal() {
|
||||
<Input
|
||||
type="time"
|
||||
value={startTime}
|
||||
handleChange={(value) => setStartTime(value)}
|
||||
onChange={(value) => setStartTime(value)}
|
||||
className="w-[137px]"
|
||||
/>
|
||||
</div>
|
||||
@@ -170,7 +170,7 @@ function CreateScheduleModal() {
|
||||
<Input
|
||||
type="time"
|
||||
value={endTime}
|
||||
handleChange={changeEndTime}
|
||||
onChange={changeEndTime}
|
||||
className="w-[137px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -106,10 +106,12 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
<div className="space-y-1">
|
||||
<Label value="Email" />
|
||||
<Input
|
||||
lowercase
|
||||
trim
|
||||
type="email"
|
||||
className="h-10"
|
||||
value={email}
|
||||
handleChange={(value) => setEmail(value)}
|
||||
onChange={(value) => setEmail(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
@@ -118,7 +120,7 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
type="tel"
|
||||
className="h-10"
|
||||
value={phone}
|
||||
handleChange={(value) => setPhone(value)}
|
||||
onChange={(value) => setPhone(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
@@ -126,7 +128,7 @@ function CreateScheduledSessionModal({ buildId, startAt, duration }: Props) {
|
||||
<Input
|
||||
className="h-10"
|
||||
value={name}
|
||||
handleChange={(value) => setName(value)}
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -97,25 +97,27 @@ function CreateUserModal({ companyId }: Props) {
|
||||
<p className="text-xl font-semibold">Новый пользователь</p>
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
||||
<Input
|
||||
required
|
||||
autoFocus
|
||||
placeholder="Имя Фамилия"
|
||||
className="w-64"
|
||||
handleChange={(value) => setName(value)}
|
||||
autoFocus
|
||||
required
|
||||
onChange={(value) => setName(value)}
|
||||
/>
|
||||
<Input
|
||||
required
|
||||
lowercase
|
||||
trim
|
||||
placeholder="Email (Логин)"
|
||||
className="w-64"
|
||||
handleChange={(value) => setUsername(value)}
|
||||
required
|
||||
onChange={(value) => setUsername(value)}
|
||||
/>
|
||||
<Input
|
||||
required
|
||||
autoComplete="new-password"
|
||||
type="password"
|
||||
placeholder="Пароль"
|
||||
className="w-64"
|
||||
handleChange={(value) => setPassword(value)}
|
||||
required
|
||||
onChange={(value) => setPassword(value)}
|
||||
/>
|
||||
<select
|
||||
className="px-3 py-2 border border-gray-300 rounded-lg outline-none"
|
||||
|
||||
@@ -126,14 +126,14 @@ function EditUserModal({ companyId, userId }: Props) {
|
||||
placeholder="Имя Фамилия"
|
||||
className="w-64"
|
||||
value={name}
|
||||
handleChange={(value) => setName(value)}
|
||||
onChange={(value) => setName(value)}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
placeholder="Email (Логин)"
|
||||
className="w-64"
|
||||
value={username}
|
||||
handleChange={(value) => setUsername(value)}
|
||||
onChange={(value) => setUsername(value)}
|
||||
required
|
||||
/>
|
||||
<select
|
||||
|
||||
@@ -95,7 +95,7 @@ function SettingsModal() {
|
||||
required
|
||||
className="w-full"
|
||||
value={oldPassword}
|
||||
handleChange={(value) => setOldPassword(value)}
|
||||
onChange={(value) => setOldPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
@@ -105,7 +105,7 @@ function SettingsModal() {
|
||||
required
|
||||
className="w-full"
|
||||
value={newPassword}
|
||||
handleChange={(value) => setNewPassword(value)}
|
||||
onChange={(value) => setNewPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -54,11 +54,13 @@ function LoginPage() {
|
||||
<div className="flex flex-col gap-1">
|
||||
<Label value="Email" />
|
||||
<Input
|
||||
lowercase
|
||||
trim
|
||||
type="email"
|
||||
placeholder="example@gmail.com"
|
||||
autoFocus
|
||||
required
|
||||
handleChange={(value) => setUsername(value)}
|
||||
onChange={(value) => setUsername(value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
@@ -67,7 +69,7 @@ function LoginPage() {
|
||||
type="password"
|
||||
placeholder="********"
|
||||
required
|
||||
handleChange={(value) => setPassword(value)}
|
||||
onChange={(value) => setPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -66,7 +66,7 @@ function ResetPasswordConfirmPage() {
|
||||
autoFocus
|
||||
required
|
||||
value={password}
|
||||
handleChange={(value) => setPassword(value)}
|
||||
onChange={(value) => setPassword(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -60,11 +60,13 @@ function ResetPasswordPage() {
|
||||
<div className="flex flex-col gap-1">
|
||||
<Label value="Email" />
|
||||
<Input
|
||||
lowercase
|
||||
trim
|
||||
type="email"
|
||||
placeholder="mail@example.com"
|
||||
autoFocus
|
||||
required
|
||||
handleChange={(value) => setUsername(value)}
|
||||
onChange={(value) => setUsername(value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,8 @@ const userSchema = new Schema(
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
trim: true,
|
||||
lowercase: true,
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
|
||||
@@ -8,13 +8,16 @@ import { createSecretKey } from "crypto";
|
||||
const router = Router();
|
||||
|
||||
router.post("/", async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
const username = req.body.username.toLowerCase().trim();
|
||||
const { password } = req.body;
|
||||
|
||||
if (!username || !password) {
|
||||
return res.json({ error: "Неверный логин или пароль" });
|
||||
}
|
||||
|
||||
const user = await User.findOne({ username }).lean();
|
||||
const user = await User.findOne({
|
||||
username: { $regex: new RegExp(username, "i") },
|
||||
}).lean();
|
||||
|
||||
if (!user) {
|
||||
return res.json({ error: "Неверный логин или пароль" });
|
||||
|
||||
Reference in New Issue
Block a user