File size: 4,854 Bytes
01d5a5d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { Spin } from 'antd';
import { useCallback, useEffect } from 'react';
import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  GlobalOutlined,
  DoubleRightOutlined,
  SyncOutlined
} from '@ant-design/icons';
import { useUploadStore } from '@/store/useUploadStore';
import { useLoadInfoStore } from '@/store/useLoadInfoStore';
import classNames from 'classnames';
import LoadMore from '../LoadMore';

const colorClasses = [
  'bg-red-500',
  'bg-pink-500',
  'bg-purple-500',
  'bg-indigo-500',
  'bg-blue-500',
  'bg-cyan-500',
  'bg-teal-500',
  'bg-green-500',
  'bg-lime-500',
  'bg-yellow-500',
  'bg-amber-500',
  'bg-orange-500'
];

const NetWorkMemberList = () => {
  const loading = useUploadStore((state) => state.loading);
  const total = useUploadStore((state) => state.total);
  const uploads = useUploadStore((state) => state.uploads);
  const fetchUploadList = useUploadStore((state) => state.fetchUploadList);
  const loadInfo = useLoadInfoStore((state) => state.loadInfo);

  useEffect(() => {
    fetchUploadList();
  }, []);

  const getRandomColor = (str: string) => {
    if (!str) return 'bg-gray-400';

    let hash = 0;

    for (let i = 0; i < str.length; i++) {
      hash = str.charCodeAt(i) + ((hash << 5) - hash);
    }

    const index = Math.abs(hash) % colorClasses.length;

    return colorClasses[index];
  };

  const renderUploadList = useCallback(() => {
    return uploads?.map((upload) => {
      const uploadStatus =
        upload.instance_id == loadInfo?.instance_id ? loadInfo?.status : upload?.status;

      return (
        <div
          key={upload?.instance_id}
          className={classNames(
            'flex items-center justify-between px-4 py-3 rounded-lg shadow-sm transition-all duration-200 hover:shadow-md border ',
            uploadStatus === 'online' ? 'bg-blue-50 border-blue-100' : 'bg-gray-50 border-gray-200',
            'group'
          )}
          onClick={() => {
            window.open(
              `https://app.secondme.io/${upload.upload_name}/${upload.instance_id}`,
              '_blank'
            );
          }}
        >
          <div className="flex items-center gap-3 w-full">
            <div
              className={`flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center text-white ${getRandomColor(upload?.upload_name)}`}
            >
              {upload?.upload_name ? upload?.upload_name.charAt(0).toUpperCase() : '?'}
            </div>
            <div>
              <div className={`font-medium text-gray-700`}>{upload?.upload_name || 'Unknown'}</div>
              <div className="flex items-center gap-2 mt-1">
                <div
                  className={`px-2 py-0.5 text-xs rounded-full flex items-center gap-1.5 ${
                    uploadStatus === 'offline'
                      ? 'bg-gray-100 text-gray-800'
                      : uploadStatus === 'registered'
                        ? 'bg-yellow-100 text-yellow-800'
                        : 'bg-green-100 text-green-800'
                  }`}
                >
                  {uploadStatus === 'offline' ? (
                    <CloseCircleOutlined className="text-gray-500" />
                  ) : uploadStatus === 'registered' ? (
                    <SyncOutlined className="text-yellow-600" spin />
                  ) : (
                    <CheckCircleOutlined className="text-green-600" />
                  )}
                  {uploadStatus || 'Unknown'}
                </div>
              </div>
            </div>
          </div>

          <DoubleRightOutlined
            className="text-[12px] !text-blue-500 transition-colors"
            style={{ fontSize: '12px' }}
          />
        </div>
      );
    });
  }, [uploads, loadInfo]);

  if (loading && uploads.length == 0) {
    return <Spin className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" />;
  }

  if (uploads.length === 0) {
    return (
      <div className="text-gray-500 text-sm p-8 bg-gray-50 rounded-lg border border-gray-200 text-center shadow-sm">
        <div className="flex justify-center mb-4">
          <div className="w-16 h-16 bg-gray-200 rounded-full flex items-center justify-center text-gray-400">
            <GlobalOutlined style={{ fontSize: '24px' }} />
          </div>
        </div>
        <p className="text-gray-600 font-medium">Network is Empty</p>
        <p className="text-sm text-gray-400 mt-2">Be the first to join the Second Me network!</p>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full gap-2">
      {renderUploadList()}
      {total !== uploads.length && (
        <LoadMore
          className="my-5"
          loadMore={() => fetchUploadList(false)}
          scrollContainerId="#netWorkMemberScrollList"
        />
      )}
    </div>
  );
};

export default NetWorkMemberList;