File size: 4,327 Bytes
f0743f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import React from 'react';
import { Globe, Shield } from 'lucide-react';
import { ResourceType } from 'librechat-data-provider';
import { Switch, InfoHoverCard, ESide, Label } from '@librechat/client';
import type { AccessRoleIds } from 'librechat-data-provider';
import AccessRolesPicker from './AccessRolesPicker';
import { useLocalize } from '~/hooks';
import { cn } from '~/utils';

interface PublicSharingToggleProps {
  isPublic: boolean;
  publicRole?: AccessRoleIds;
  onPublicToggle: (isPublic: boolean) => void;
  onPublicRoleChange: (role: AccessRoleIds) => void;
  resourceType?: ResourceType;
  className?: string;
}

const accessDescriptions: Record<ResourceType, 'com_ui_agent' | 'com_ui_prompt'> = {
  [ResourceType.AGENT]: 'com_ui_agent',
  [ResourceType.PROMPTGROUP]: 'com_ui_prompt',
};

export default function PublicSharingToggle({
  isPublic,
  publicRole,
  onPublicToggle,
  onPublicRoleChange,
  resourceType = ResourceType.AGENT,
  className,
}: PublicSharingToggleProps) {
  const localize = useLocalize();

  const handleToggle = React.useCallback(
    (checked: boolean) => {
      onPublicToggle(checked);
    },
    [onPublicToggle],
  );

  return (
    <div className={cn('space-y-4', className)}>
      {/* Main toggle section */}
      <div className="group relative rounded-lg">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div
              className={cn(
                'transition-colors duration-200',
                isPublic ? 'text-blue-600 dark:text-blue-500' : 'text-text-secondary',
              )}
            >
              <Globe className="size-5" />
            </div>
            <div className="flex items-center gap-2">
              <Label
                htmlFor="share-everyone-toggle"
                className="cursor-pointer text-sm font-medium text-text-primary"
              >
                {localize('com_ui_share_everyone')}
              </Label>
              <InfoHoverCard
                side={ESide.Top}
                text={localize('com_ui_share_everyone_description_var', {
                  resource:
                    localize(accessDescriptions[resourceType]) || localize('com_ui_resource'),
                })}
              />
            </div>
          </div>
          <Switch
            id="share-everyone-toggle"
            checked={isPublic}
            onCheckedChange={handleToggle}
            aria-label={localize('com_ui_share_everyone')}
          />
        </div>
      </div>

      {/* Permission level section with smooth animation */}
      <div
        className={cn(
          'transition-all duration-300 ease-in-out',
          isPublic ? 'max-h-32 opacity-100' : 'max-h-0 opacity-0',
        )}
        style={{ overflow: isPublic ? 'visible' : 'hidden' }}
      >
        <div
          className={cn(
            'rounded-lg transition-all duration-300',
            isPublic ? 'bg-surface-secondary/50 translate-y-0' : '-translate-y-2',
          )}
        >
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div
                className={cn(
                  'transition-all duration-300',
                  isPublic
                    ? 'scale-100 text-blue-600 dark:text-blue-500'
                    : 'scale-95 text-text-secondary',
                )}
              >
                <Shield className="size-5" />
              </div>
              <div className="flex flex-col gap-0.5">
                <Label htmlFor="permission-level" className="text-sm font-medium text-text-primary">
                  {localize('com_ui_everyone_permission_level')}
                </Label>
              </div>
            </div>
            <div
              className={cn(
                'relative z-50 transition-all duration-300',
                isPublic ? 'scale-100 opacity-100' : 'scale-95 opacity-0',
              )}
            >
              <AccessRolesPicker
                id="permission-level"
                resourceType={resourceType}
                selectedRoleId={publicRole}
                onRoleChange={onPublicRoleChange}
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}