File size: 6,335 Bytes
6c93a54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
class CustomApiShowcase extends HTMLElement {
    static get observedAttributes() {
        return ['api-name', 'category', 'description', 'endpoint', 'docs-url'];
    }

    constructor() {
        super();
        this.apiName = 'API Name';
        this.category = 'Category';
        this.description = 'API description goes here.';
        this.endpoint = 'https://api.example.com';
        this.docsUrl = 'https://docs.example.com';
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if (oldValue !== newValue) {
            this[name] = newValue;
            this.render();
        }
    }

    connectedCallback() {
        this.render();
    }

    getCategoryColor() {
        const colors = {
            'Data Mocking': 'bg-blue-100 text-blue-800',
            'Fun & Images': 'bg-purple-100 text-purple-800',
            'Weather Data': 'bg-green-100 text-green-800',
            'Finance': 'bg-emerald-100 text-emerald-800',
            'Social': 'bg-pink-100 text-pink-800',
            'Development': 'bg-orange-100 text-orange-800',
            'Business': 'bg-indigo-100 text-indigo-800'
        };
        return colors[this.category] || 'bg-gray-100 text-gray-800';
    }

    render() {
        const categoryColor = this.getCategoryColor();
        
        this.attachShadow({ mode: 'open' });
        this.shadowRoot.innerHTML = `
            <style>
                :host {
                    display: block;
                }
                .api-card {
                    transition: all 0.3s ease;
                }
                .api-card:hover {
                    transform: translateX(5px);
                }
                .endpoint-box {
                    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
                }
                .copy-btn {
                    transition: all 0.2s ease;
                }
                .copy-btn:hover {
                    transform: scale(1.05);
                }
                .copy-btn:active {
                    transform: scale(0.95);
                }
            </style>
            <div class="api-card bg-white rounded-xl border border-gray-200 p-6 hover:border-blue-300 hover:shadow-xl">
                <div class="flex flex-col md:flex-row md:items-start md:justify-between mb-4">
                    <div class="mb-4 md:mb-0 md:mr-6">
                        <div class="flex items-center space-x-3 mb-2">
                            <h3 class="text-xl font-bold text-gray-900">${this.apiName}</h3>
                            <span class="px-3 py-1 rounded-full text-xs font-semibold ${categoryColor}">
                                ${this.category}
                            </span>
                        </div>
                        <p class="text-gray-600">${this.description}</p>
                    </div>
                    <div class="flex space-x-3">
                        <a href="${this.docsUrl}" target="_blank" class="inline-flex items-center px-4 py-2 bg-blue-50 hover:bg-blue-100 text-blue-600 font-medium rounded-lg transition duration-300">
                            <i data-feather="book-open" class="w-4 h-4 mr-2"></i>
                            Docs
                        </a>
                        <a href="/try?api=${encodeURIComponent(this.apiName)}" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white font-medium rounded-lg transition duration-300 shadow-md hover:shadow-lg">
                            <i data-feather="play" class="w-4 h-4 mr-2"></i>
                            Try It
                        </a>
                    </div>
                </div>

                <div class="mt-6">
                    <div class="flex items-center justify-between mb-2">
                        <span class="text-sm font-medium text-gray-500">Endpoint</span>
                        <button class="copy-btn flex items-center text-sm text-blue-600 hover:text-blue-800 font-medium" data-copy="${this.endpoint}">
                            <i data-feather="copy" class="w-4 h-4 mr-1"></i>
                            Copy
                        </button>
                    </div>
                    <div class="endpoint-box bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto">
                        <code class="text-sm text-gray-800">${this.endpoint}</code>
                    </div>
                </div>

                <div class="mt-6 flex items-center text-sm text-gray-500">
                    <div class="flex items-center mr-6">
                        <i data-feather="zap" class="w-4 h-4 mr-2 text-green-500"></i>
                        <span>99.9% Uptime</span>
                    </div>
                    <div class="flex items-center mr-6">
                        <i data-feather="clock" class="w-4 h-4 mr-2 text-blue-500"></i>
                        <span>&lt;100ms Response</span>
                    </div>
                    <div class="flex items-center">
                        <i data-feather="shield" class="w-4 h-4 mr-2 text-purple-500"></i>
                        <span>HTTPS Only</span>
                    </div>
                </div>
            </div>
        `;

        // Add copy functionality
        const copyBtn = this.shadowRoot.querySelector('.copy-btn');
        if (copyBtn) {
            copyBtn.addEventListener('click', async () => {
                const textToCopy = copyBtn.getAttribute('data-copy');
                try {
                    await navigator.clipboard.writeText(textToCopy);
                    const originalHTML = copyBtn.innerHTML;
                    copyBtn.innerHTML = '<i data-feather="check" class="w-4 h-4 mr-1"></i>Copied!';
                    feather.replace();
                    setTimeout(() => {
                        copyBtn.innerHTML = originalHTML;
                        feather.replace();
                    }, 2000);
                } catch (err) {
                    console.error('Failed to copy:', err);
                }
            });
        }

        // Initialize icons in shadow DOM
        setTimeout(() => {
            feather.replace();
        }, 100);
    }
}

customElements.define('custom-api-showcase', CustomApiShowcase);