Задать вопрос
  • Как двигать элемент по Y с заданным значением?

    @andry36
    Для реализации ограничения движения элемента по оси Y в пределах от 0% до 100%, необходимо добавить логику, которая будет проверять текущее значение yTranslate и ограничивать его в указанных границах.

    const Draggable = () => {
      const [isDragging, setIsDragging] = useState(false);
      const [yTranslate, setYTranslate] = useState(0); // %
      const [initialMousePosition, setInitialMousePosition] = useState(null);
    
      const onMouseDown = ({ clientY }) => {
        setInitialMousePosition(clientY);
        setIsDragging(true);
      };
    
      useEffect(() => {
        const onMouseMove = (e) => {
          if (isDragging && initialMousePosition !== null) {
            const deltaY = e.clientY - initialMousePosition;
            const containerHeight = document.querySelector(".relative").offsetHeight;
    
            // px -> %
            const deltaYPercent = (deltaY / containerHeight) * 100;
            let newTranslate = yTranslate + deltaYPercent;
    
            //  [0%, 100%]
            newTranslate = Math.max(0, Math.min(100, newTranslate));
    
            setYTranslate(newTranslate);
            setInitialMousePosition(e.clientY);
          }
        };
    
        if (isDragging) {
          window.addEventListener("mousemove", onMouseMove);
        }
        return () => window.removeEventListener("mousemove", onMouseMove);
      }, [isDragging, initialMousePosition, yTranslate]);
    
      useEffect(() => {
        const onMouseUp = () => setIsDragging(false);
        window.addEventListener("mouseup", onMouseUp);
        return () => window.removeEventListener("mouseup", onMouseUp);
      }, []);
    
      return (
        <div className="text-[15px]/[22px] bg-white">
          <div style={{ '--coverY': `${yTranslate}%` }} className="relative aspect-[640_/_200] bg-[#e5e5e5] overflow-hidden">
                 {/* не забудь повесить onMouseDown  на нужный элемент */}
          </div>
        </div>
      );
    };
    Ответ написан
    Комментировать
  • Как в Next JS, отправка файлов на сервер с указанием пути сохранения?

    @Tars_Tarkas Автор вопроса
    Junior React Developer
    может кому нибудь пригодится мое решение:

    файл api/upload/route.ts

    import mime from "mime";
    import { join } from "path";
    import { stat, mkdir, writeFile } from "fs/promises";
    import { NextRequest, NextResponse } from "next/server";
    
    export async function POST(request: NextRequest) {
      const formData = await request.formData();
      const file = formData.get("file") as Blob | null;
    
      if (!file) {
        return NextResponse.json(
          { error: "File blob is required." },
          { status: 400 }
        );
      }
      const folder = formData.get("folder") as string;
    
      const relativeUploadDir = `/portfolio/${folder}`;
      const uploadDir = join(process.cwd(), "public/", relativeUploadDir);
    
      try {
        await stat(uploadDir);
      } catch (e: any) {
        if (e.code === "ENOENT") {
          await mkdir(uploadDir, { recursive: true });
        } else {
          console.error(
            "Ошибка при попытке создать каталог при загрузке файла\n",
            e
          );
          return NextResponse.json(
            { error: "Что-то пошло не так." },
            { status: 500 }
          );
        }
      }
    
      try {
        const folderArray = [];
        const formDataEntryValues = Array.from(formData.values()) as [];
        for (const formDataEntryValue of formDataEntryValues) {
          if (
            typeof formDataEntryValue === "object" &&
            "arrayBuffer" in formDataEntryValue
          ) {
            const file = formDataEntryValue as unknown as Blob;
            const buffer = Buffer.from(await file.arrayBuffer());
            await writeFile(`${uploadDir}/${file.name}`, buffer);
            folderArray.push(`${relativeUploadDir}/${file.name}`);
          }
        }
        return NextResponse.json({ filename: folderArray });
      } catch (e) {
        console.error("Error while trying to upload a file\n", e);
        return NextResponse.json({ error: "Что-то пошло не так" }, { status: 500 });
      }
    }
    Ответ написан
    Комментировать
  • Скрытый блок появляется на секунду при обновлении страницы?

    ThunderCat
    @ThunderCat Куратор тега JavaScript
    {PHP, MySql, HTML, JS, CSS} developer
    Пр обновлении страницы он на секунду разворачивается и сворачивается обратно. Как убрать это?
    Ну так у вас элемент не имеет класса closed до момента выполнения функции, логично что загружается он открытым.

    Как убрать это?
    1) в коде добавить элементу closed, и уже при вызове функции убирать, если в куке нужный флаг. Задержка тоже будет, но уже на открытие, что не так страшно.
    2) На стороне сервера проверять куку, и добавлять в разметку нужный класс еще на сервере.
    Ответ написан
    Комментировать
  • Как в Django определять админа, персонал, какую-то роль (которую определили в админке), как назначать свежезареганному пользователю роль?

    JawsIk
    @JawsIk Автор вопроса
    Python Django, Lua, ЧПУ-станки(ArtCam, Aspire)
    Итак, как было в теме, я задавал два вопроса. Отвечу на них по порядку, чтобы людям сразу наглядно было понятно что сделать, чтобы получить результат. Очень меня печалит документация по Django. Вроде бы всё есть, но в итоге нет примеров. А как сказал мой один хороший учитель (не по Django а вообще по программированию): "Документация без примеров кода, это просто справочник. И если ты не специалист, то грош цена такому справочнику". Поэтому я просто приведу два примера кода, после которого сразу всё станет ясно.

    Вопрос 1: Опознавание ролей (групп) программно.
    В примере будет показан программный код метода account_view из файла views.py, который будет опознавать разные группы пользователей. Для примера в админке была создана группа manager. Ей не были даны специальные разрешения (permissions) и она служит лишь для декоративного разделения, но в программном коде даже такое декоративное разделение позволяет прекрасно опознавать и распределять пользователей. Так же прошу не обращать на функционал корзинки, здесь он оставлен только для того, чтобы показать на какой стадии нужно вставлять условия. Так же нужно понимать, что в каждом условии кроме имени шаблона могут быть (при необходимости) добавлены свои параметры, которые потом можно передать в шаблон.
    def account_view(request):
    
        cart = Cart()
        cart_id = cart.get_cart_id(request)
        items_in_cart = CartItems.objects.filter(cart_id=cart_id)
    
        # если не опознан, то дуй на страницу регистрирации
        if not request.user.is_authenticated:
            return HttpResponseRedirect(reverse('registration'))
    
        # если это суперпользователь
        if request.user.is_superuser:
            template = 'account_admin.html'
        # или если это пользователь с галочкой персонал, а так же принадлежащий группе manager
        elif request.user.is_staff and request.user.groups.filter(name='manager').exists():
            template = 'account_personal_role.html'
        # или если это просто пользователь с галочкой персонал
        elif request.user.is_staff:
            template = 'account_personal.html'
        # или если это пользователь принадлежащий группе manager
        elif request.user.groups.filter(name='manager').exists():
            template = 'account_role.html'
        # иначе все остальные (обычные пользователи)
        else:
            template = 'account.html'
    
        # сортировка выдачи заказов в обратном порядке (от последнего к первому)    
        list_orders = Order.objects.filter(user=request.user).order_by('-id')
        orders = OrderItems.add_order_info(request, list_orders)
    
        context = {
            'title': 'Кабинет пользователя',
            'orders': orders,
            'cart': items_in_cart,
            'total_cost': cart_id.total_cost,
        }
        return render(request, template, context=context)

    Как видно из кода здесь имеет место быть некоторая последовательность. В частности, если второе условие (первый elif) опустить ниже, то возможна неверная работа, т.к. тогда пользователь принадлежащий группе manager и с галочкой персонала, может легко заскочить в чужой шаблон (по одному условию), поэтому при создании сложных условий, этот момент нужно учитывать.

    Вопрос 2: Программное добавление пользователей в группу (или в несколько сразу)
    Иногда бывает, что (например) при регистрации, нужно сразу добавить пользователя в определённую группу. Для примера была создана группа clients. Это чисто декоративное разделение. Группа не имеет никаких разрешений в админке, но выполняет свою задачу. Ниже представлен код метода registration_view из файла views.py , т.е. регистрации пользователя и этот новый пользователь после регистрации будет уже принадлежать группе clients. Кстати, чтобы код работал нужно выполнить необходимый импорт, это тоже в коде показано.
    ...
    from django.contrib.auth.models import Group
    ...
    
    def registration_view(request):
    
        # (предотвращаем заход по прямой ссылке)
        # если авторизован, то
        if request.user.is_authenticated:
            return HttpResponseRedirect(reverse('account'))
    
        form = RegistrationForm(request.POST or None)
        if form.is_valid():
            new_user = form.save(commit=False)
            new_user.username = form.cleaned_data['username']
            new_user.set_password(form.cleaned_data['password'])  # вот из-за этой бяки вся засада была у меня с паролями ЗАПОМНИ!!!!!!
            new_user.email = form.cleaned_data['email']
            new_user.first_name = form.cleaned_data['first_name']
            new_user.last_name = form.cleaned_data['last_name']
            new_user.save()
    
            # после собственно регистрации (сохранения нового) пользователя его можно добавить к группам
            new_user.groups.add(Group.objects.get(name='clients'))
    	# new_user.groups.add(Group.objects.get(name='manager'))  # и в ещё одну группу работает тоже
    
            login_user = authenticate(request, username=form.cleaned_data['username'], password=form.cleaned_data['password'])
            if login_user:
                login(request, login_user)
                return HttpResponseRedirect(reverse('account'))
    
        context = {
            'title': 'Регистрация',
            'form': form,
        }
        return render(request, 'registration.html', context)

    Как видно в коде после создания пользователя, он добавляется к (уже созданной предварительно) группе и теперь зайдя в админку, мы это можем легко проверить. Кроме того, в коде закомментирована строчка с добавлением в ещё одну группу manager. Если её раскомментировать, то пользователь будет добавлен сразу в две группы. Т.о. можно добавлять пользователей сразу в несколько групп (если в этом есть необходимость). Естественно нужно понимать, что подобное добавление в группу можно делать не только при регистрации, но видя этот код, сделать необходимое решение уже не должно составлять большого труда.

    Надеюсь код пригодиться людям.
    Ответ написан
    Комментировать