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