JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr{ gilour

File "comments-datatable-page.tsx"

Full Path: /home/markqprx/iniasli.pro/client/comments/comments-datatable-page/comments-datatable-page.tsx
File size: 4.97 KB
MIME-type: text/plain
Charset: utf-8

import React, {useCallback, useMemo, useState} from 'react';
import {Trans} from '@common/i18n/trans';
import clsx from 'clsx';
import {StaticPageTitle} from '@common/seo/static-page-title';
import {DataTableHeader} from '@common/datatable/data-table-header';
import {useBackendFilterUrlParams} from '@common/datatable/filters/backend-filter-url-params';
import {
  GetDatatableDataParams,
  useDatatableData,
} from '@common/datatable/requests/paginated-resources';
import {Comment} from '@common/comments/comment';
import {FilterList} from '@common/datatable/filters/filter-list/filter-list';
import {SelectedStateDatatableHeader} from '@common/datatable/selected-state-datatable-header';
import {AnimatePresence} from 'framer-motion';
import {DeleteCommentsButton} from '@common/comments/comments-datatable-page/delete-comments-button';
import {CommentDatatableItem} from '@common/comments/comments-datatable-page/comment-datatable-item';
import {DataTablePaginationFooter} from '@common/datatable/data-table-pagination-footer';
import {DataTableEmptyStateMessage} from '@common/datatable/page/data-table-emty-state-message';
import publicDiscussionsImage from './public-discussion.svg';
import {FullPageLoader} from '@common/ui/progress/full-page-loader';
import {Commentable} from '@common/comments/commentable';
import {CommentsDatatableFilters} from '@common/comments/comments-datatable-page/comments-datatable-filters';

interface Props {
  hideTitle?: boolean;
  commentable?: Commentable;
}
export function CommentsDatatablePage({hideTitle, commentable}: Props) {
  const filters = useMemo(() => {
    return CommentsDatatableFilters.filter(
      f => f.key !== 'commentable_id' || !commentable,
    );
  }, [commentable]);
  const {encodedFilters} = useBackendFilterUrlParams(filters);
  const [params, setParams] = useState<GetDatatableDataParams>({perPage: 15});
  const [selectedComments, setSelectedComments] = useState<number[]>([]);
  const query = useDatatableData<Comment>(
    'comment',
    {
      ...params,
      with: 'commentable',
      withCount: 'reports',
      filters: encodedFilters,
      commentable_type: commentable?.model_type,
      commentable_id: commentable?.id,
    },
    undefined,
    () => {
      setSelectedComments([]);
    },
  );

  const toggleComment = useCallback(
    (id: number) => {
      const newValues = [...selectedComments];
      if (!newValues.includes(id)) {
        newValues.push(id);
      } else {
        const index = newValues.indexOf(id);
        newValues.splice(index, 1);
      }
      setSelectedComments(newValues);
    },
    [selectedComments, setSelectedComments],
  );

  const isFiltering = !!(params.query || params.filters || encodedFilters);
  const pagination = query.data?.pagination;

  return (
    <div className={clsx(!hideTitle && 'p-12 md:p-24')}>
      <div className={clsx('mb-16')}>
        <StaticPageTitle>
          <Trans message="Comments" />
        </StaticPageTitle>
        {!hideTitle && (
          <h1 className="text-3xl font-light">
            <Trans message="Comments" />
          </h1>
        )}
      </div>
      <div>
        <AnimatePresence initial={false} mode="wait">
          {selectedComments.length ? (
            <SelectedStateDatatableHeader
              selectedItemsCount={selectedComments.length}
              actions={
                <DeleteCommentsButton
                  size="sm"
                  variant="flat"
                  commentIds={selectedComments}
                />
              }
              key="selected"
            />
          ) : (
            <DataTableHeader
              filters={filters}
              searchValue={params.query}
              onSearchChange={query => setParams({...params, query})}
              key="default"
            />
          )}
        </AnimatePresence>
        <FilterList className="mb-14" filters={filters} />

        {query.isLoading ? (
          <FullPageLoader className="min-h-200" />
        ) : (
          <div className="rounded border-x border-t">
            {pagination?.data.map(comment => (
              <CommentDatatableItem
                key={comment.id}
                comment={comment}
                isSelected={selectedComments.includes(comment.id)}
                onToggle={() => toggleComment(comment.id)}
              />
            ))}
          </div>
        )}

        {(query.isFetched || query.isPlaceholderData) &&
        !pagination?.data.length ? (
          <DataTableEmptyStateMessage
            className="pt-50"
            isFiltering={isFiltering}
            image={publicDiscussionsImage}
            title={<Trans message="No comments have been created yet" />}
            filteringTitle={<Trans message="No matching comments" />}
          />
        ) : undefined}

        <DataTablePaginationFooter
          className="mt-10"
          query={query}
          onPageChange={page => setParams({...params, page})}
          onPerPageChange={perPage => setParams({...params, perPage})}
        />
      </div>
    </div>
  );
}