File size: 3,427 Bytes
0a8fe79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React, { useState } from 'react';

export default function InviteModal({ server, onClose, token }) {
  const [inviteCode, setInviteCode] = useState('');
  const [loading, setLoading] = useState(false);
  const [copied, setCopied] = useState(false);
  const [error, setError] = useState('');

  const generateInvite = async () => {
    setLoading(true);
    setError('');
    try {
      const res = await fetch(`/api/invites/servers/${server.id}/invites`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
      });
      if (!res.ok) throw new Error('Failed to generate invite');
      const data = await res.json();
      setInviteCode(data.code);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const inviteLink = inviteCode ? `${window.location.origin}/invite/${inviteCode}` : '';

  const copyToClipboard = async () => {
    try {
      await navigator.clipboard.writeText(inviteLink);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {
      // Fallback
      const ta = document.createElement('textarea');
      ta.value = inviteLink;
      document.body.appendChild(ta);
      ta.select();
      document.execCommand('copy');
      document.body.removeChild(ta);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={onClose}>
      <div className="bg-[#1e1e22] rounded-xl p-6 max-w-md w-full mx-4 shadow-2xl" onClick={e => e.stopPropagation()}>
        <h2 className="text-lg font-bold text-gray-100 mb-1">
          Invite Friends to <span className="text-[#FFD700]">{server?.name}</span>
        </h2>
        <p className="text-gray-500 text-sm mb-6">Share this link to let others join your server</p>

        {!inviteCode ? (
          <button
            onClick={generateInvite}
            disabled={loading}
            className="w-full py-2.5 bg-[#FFD700] text-black font-semibold rounded-lg hover:bg-yellow-400 disabled:opacity-50 transition-colors duration-200"
          >
            {loading ? 'Generating…' : 'Generate Invite Link'}
          </button>
        ) : (
          <div className="space-y-3">
            <div className="flex items-center gap-2">
              <input
                type="text"
                readOnly
                value={inviteLink}
                className="flex-1 bg-[#111114] border border-[#3a3a42] rounded-lg px-4 py-2.5 text-gray-100 text-sm outline-none"
              />
              <button
                onClick={copyToClipboard}
                className={`px-4 py-2.5 rounded-lg font-semibold text-sm transition-colors duration-200 flex-shrink-0 ${
                  copied
                    ? 'bg-green-600 text-white'
                    : 'bg-[#FFD700] text-black hover:bg-yellow-400'
                }`}
              >
                {copied ? 'Copied!' : 'Copy'}
              </button>
            </div>
          </div>
        )}

        {error && <p className="text-red-400 text-sm mt-3">{error}</p>}

        <button
          onClick={onClose}
          className="mt-4 w-full py-2 text-gray-400 hover:text-gray-200 text-sm transition-colors duration-200"
        >
          Close
        </button>
      </div>
    </div>
  );
}