aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/(dash)/home/queryinput.tsx
blob: d0c27b8deb0c0390b324ac7134fa2242c67d10a3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"use client";

import { ArrowRightIcon } from "@repo/ui/icons";
import Image from "next/image";
import React, { useEffect, useMemo, useState } from "react";
import Divider from "@repo/ui/shadcn/divider";
import { MultipleSelector, Option } from "@repo/ui/shadcn/combobox";
import { useRouter } from "next/navigation";
import { getSpaces } from "@/app/actions/fetchers";

function QueryInput({
  initialQuery = "",
  initialSpaces = [],
  disabled = false,
}: {
  initialQuery?: string;
  initialSpaces?: {
    id: number;
    name: string;
  }[];
  disabled?: boolean;
}) {
  const [q, setQ] = useState(initialQuery);

  const [selectedSpaces, setSelectedSpaces] = useState<number[]>([]);

  const { push } = useRouter();

  const parseQ = () => {
    // preparedSpaces is list of spaces selected by user, with id and name
    const preparedSpaces = initialSpaces
      .filter((x) => selectedSpaces.includes(x.id))
      .map((x) => {
        return {
          id: x.id,
          name: x.name,
        };
      });

    const newQ =
      "/chat?q=" +
      encodeURI(q) +
      (selectedSpaces ? "&spaces=" + JSON.stringify(preparedSpaces) : "");

    return newQ;
  };

  const options = useMemo(
    () =>
      initialSpaces.map((x) => ({
        label: x.name,
        value: x.id.toString(),
      })),
    [initialSpaces],
  );

  return (
    <div>
      <div className="bg-secondary rounded-t-[24px]">
        {/* input and action button */}
        <form action={async () => push(parseQ())} className="flex gap-4 p-3">
          <textarea
            name="q"
            cols={30}
            rows={4}
            className="bg-transparent pt-2.5 text-base text-[#989EA4] focus:text-foreground duration-200 tracking-[3%] outline-none resize-none w-full p-4"
            placeholder="Ask your second brain..."
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                e.preventDefault();
                if (!e.shiftKey) push(parseQ());
              }
            }}
            onChange={(e) => setQ(e.target.value)}
            value={q}
            disabled={disabled}
          />

          <button
            type="submit"
            disabled={disabled}
            className="h-12 w-12 rounded-[14px] bg-[#21303D] all-center shrink-0 hover:brightness-125 duration-200 outline-none focus:outline focus:outline-primary active:scale-90"
          >
            <Image src={ArrowRightIcon} alt="Right arrow icon" />
          </button>
        </form>

        <Divider />
      </div>
      {/* selected sources */}
      <div className="flex items-center gap-6 p-2 h-auto bg-secondary rounded-b-[24px]">
        <MultipleSelector
          key={options.length}
          disabled={disabled}
          defaultOptions={options}
          onChange={(e) => setSelectedSpaces(e.map((x) => parseInt(x.value)))}
          placeholder="Focus on specific spaces..."
          emptyIndicator={
            <p className="text-center text-lg leading-10 text-gray-600 dark:text-gray-400">
              no results found.
            </p>
          }
        />
      </div>
    </div>
  );
}

export default QueryInput;