File size: 3,737 Bytes
65d68f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import { Paperclip, Plus } from "lucide-react";
import { uploadMenuItems } from "./constants";
import type { SourceDraftMode, UploadMenuAction } from "./types";

function nextDraftModeForAction(action: UploadMenuAction): SourceDraftMode {
  if (action === "link") return "link";
  if (action === "syllabus") return "syllabus";
  if (action === "text") return "text";
  return null;
}

export function ComposerPlusMenu({
  plusOpen,
  onPlusOpenChange,
  onOpenMaterialPicker,
  onOpenPaperPicker,
  onSourceDraftModeChange,
}: {
  plusOpen: boolean;
  onPlusOpenChange: (open: boolean) => void;
  onOpenMaterialPicker: () => void;
  onOpenPaperPicker: () => void;
  onSourceDraftModeChange: (mode: SourceDraftMode) => void;
}) {
  function handleMenuAction(action: UploadMenuAction, enabled: boolean) {
    if (!enabled) return;
    if (action === "material") {
      onPlusOpenChange(false);
      onOpenMaterialPicker();
      return;
    }
    if (action === "paper") {
      onPlusOpenChange(false);
      onOpenPaperPicker();
      return;
    }
    const draftMode = nextDraftModeForAction(action);
    if (draftMode) {
      onSourceDraftModeChange(draftMode);
      onPlusOpenChange(false);
    }
  }

  return (
    <div className="relative flex items-center gap-1 text-white/54">
      <button
        type="button"
        onClick={() => onPlusOpenChange(!plusOpen)}
        aria-expanded={plusOpen}
        aria-label="Open add source menu"
        className="inline-flex size-9 items-center justify-center rounded-full border border-white/[0.1] bg-white/[0.04] transition hover:border-white/[0.2] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22"
      >
        <Plus className="size-[1.05rem]" />
      </button>
      <button
        type="button"
        onClick={onOpenMaterialPicker}
        aria-label="Attach file"
        className="inline-flex size-9 items-center justify-center rounded-full transition hover:bg-white/[0.06] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22"
      >
        <Paperclip className="size-[1.05rem]" />
      </button>

      {plusOpen ? (
        <div className="absolute bottom-12 left-0 z-30 max-h-[18rem] w-[min(21rem,88vw)] overflow-y-auto rounded-2xl border border-white/[0.1] bg-[#090909] p-2 shadow-[0_24px_80px_rgba(0,0,0,0.62)] [scrollbar-width:none] sm:max-h-[28rem] [&::-webkit-scrollbar]:hidden">
          {uploadMenuItems.map((item) => {
            const Icon = item.icon;
            return (
              <button
                key={item.label}
                type="button"
                disabled={!item.enabled}
                onClick={() => handleMenuAction(item.action, item.enabled)}
                className="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left transition hover:bg-white/[0.055] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:cursor-not-allowed disabled:opacity-38"
              >
                <span className="grid size-9 shrink-0 place-items-center rounded-xl border border-white/[0.08] bg-white/[0.035] text-white/60">
                  <Icon className="size-4" />
                </span>
                <span className="min-w-0 flex-1">
                  <span className="block text-sm font-semibold text-white/82">{item.label}</span>
                  <span className="block truncate text-xs text-white/38">{item.description}</span>
                </span>
                {!item.enabled ? <span className="text-[10px] font-bold uppercase text-white/28">Soon</span> : null}
              </button>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}