sitepaige-mcp-server 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/form.tsx +133 -6
- package/components/login.tsx +173 -21
- package/components/menu.tsx +128 -3
- package/components/testimonial.tsx +1 -1
- package/defaultapp/api/Auth/route.ts +105 -3
- package/defaultapp/api/Auth/signup/route.ts +143 -0
- package/defaultapp/api/Auth/verify-email/route.ts +98 -0
- package/defaultapp/db-password-auth.ts +325 -0
- package/defaultapp/storage/email.ts +162 -0
- package/dist/blueprintWriter.js +15 -1
- package/dist/blueprintWriter.js.map +1 -1
- package/dist/components/form.tsx +133 -6
- package/dist/components/login.tsx +173 -21
- package/dist/components/menu.tsx +128 -3
- package/dist/components/testimonial.tsx +1 -1
- package/dist/defaultapp/api/Auth/route.ts +105 -3
- package/dist/defaultapp/api/Auth/signup/route.ts +143 -0
- package/dist/defaultapp/api/Auth/verify-email/route.ts +98 -0
- package/dist/defaultapp/db-password-auth.ts +325 -0
- package/dist/defaultapp/storage/email.ts +162 -0
- package/dist/generators/apis.js +1 -0
- package/dist/generators/apis.js.map +1 -1
- package/dist/generators/defaultapp.js +2 -2
- package/dist/generators/defaultapp.js.map +1 -1
- package/dist/generators/env-example-template.txt +27 -0
- package/dist/generators/images.js +38 -13
- package/dist/generators/images.js.map +1 -1
- package/dist/generators/pages.js +1 -1
- package/dist/generators/pages.js.map +1 -1
- package/dist/generators/sql.js +19 -0
- package/dist/generators/sql.js.map +1 -1
- package/dist/generators/views.js +16 -1
- package/dist/generators/views.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { randomBytes } from 'crypto';
|
|
2
|
+
|
|
3
|
+
// Simple in-memory storage for email tracking (in production, use a database)
|
|
4
|
+
const emailHistory: Map<string, any> = new Map();
|
|
5
|
+
|
|
6
|
+
export interface EmailOptions {
|
|
7
|
+
to: string | string[];
|
|
8
|
+
from: string;
|
|
9
|
+
subject: string;
|
|
10
|
+
html?: string;
|
|
11
|
+
text?: string;
|
|
12
|
+
cc?: string | string[];
|
|
13
|
+
bcc?: string | string[];
|
|
14
|
+
replyTo?: string | string[];
|
|
15
|
+
attachments?: Array<{
|
|
16
|
+
filename: string;
|
|
17
|
+
content: string; // base64 encoded content
|
|
18
|
+
contentType?: string;
|
|
19
|
+
}>;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
tags?: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
value: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Send email function that sends emails via the Resend API
|
|
29
|
+
* @param options Email options including to, from, subject, message content, etc.
|
|
30
|
+
* @returns Promise that resolves to the email ID from Resend
|
|
31
|
+
*/
|
|
32
|
+
export async function send_email(options: EmailOptions): Promise<string> {
|
|
33
|
+
console.log(`📧 Sending email to: ${Array.isArray(options.to) ? options.to.join(', ') : options.to}`);
|
|
34
|
+
console.log(`📧 Subject: ${options.subject}`);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
// Get API key from environment
|
|
38
|
+
const apiKey = process.env.RESEND_API_KEY;
|
|
39
|
+
if (!apiKey) {
|
|
40
|
+
throw new Error('RESEND_API_KEY environment variable is not set');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Prepare request body for Resend API
|
|
44
|
+
const requestBody: any = {
|
|
45
|
+
to: options.to,
|
|
46
|
+
from: options.from,
|
|
47
|
+
subject: options.subject,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Add optional fields
|
|
51
|
+
if (options.html) requestBody.html = options.html;
|
|
52
|
+
if (options.text) requestBody.text = options.text;
|
|
53
|
+
if (options.cc) requestBody.cc = options.cc;
|
|
54
|
+
if (options.bcc) requestBody.bcc = options.bcc;
|
|
55
|
+
if (options.replyTo) requestBody.reply_to = options.replyTo;
|
|
56
|
+
if (options.headers) requestBody.headers = options.headers;
|
|
57
|
+
if (options.tags) requestBody.tags = options.tags;
|
|
58
|
+
|
|
59
|
+
// Handle attachments
|
|
60
|
+
if (options.attachments && options.attachments.length > 0) {
|
|
61
|
+
requestBody.attachments = options.attachments.map(att => ({
|
|
62
|
+
filename: att.filename,
|
|
63
|
+
content: att.content,
|
|
64
|
+
content_type: att.contentType,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Make API request to Resend
|
|
69
|
+
const response = await fetch('https://api.resend.com/emails', {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
73
|
+
'Content-Type': 'application/json',
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify(requestBody),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
const errorData = await response.json().catch(() => ({ message: 'Unknown error' }));
|
|
80
|
+
throw new Error(`Resend API error: ${response.status} - ${errorData.message || response.statusText}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const result = await response.json();
|
|
84
|
+
const emailId = result.id;
|
|
85
|
+
|
|
86
|
+
// Store email metadata
|
|
87
|
+
const emailKey = `${Date.now()}_${randomBytes(6).toString('hex')}`;
|
|
88
|
+
emailHistory.set(emailKey, {
|
|
89
|
+
id: emailId,
|
|
90
|
+
to: options.to,
|
|
91
|
+
from: options.from,
|
|
92
|
+
subject: options.subject,
|
|
93
|
+
sentAt: new Date().toISOString(),
|
|
94
|
+
status: 'sent',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
console.log(`✅ Email sent successfully. ID: ${emailId}`);
|
|
98
|
+
|
|
99
|
+
return emailId;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error('❌ Error sending email:', error);
|
|
102
|
+
throw new Error(`Failed to send email: ${error}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get email status by ID
|
|
108
|
+
* @param emailId The email ID returned from send_email
|
|
109
|
+
* @returns Email metadata or undefined if not found
|
|
110
|
+
*/
|
|
111
|
+
export async function getEmailStatus(emailId: string): Promise<any> {
|
|
112
|
+
// Find email in history by Resend ID
|
|
113
|
+
for (const [key, data] of emailHistory.entries()) {
|
|
114
|
+
if (data.id === emailId) {
|
|
115
|
+
return data;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// If not found locally, could query Resend API for status
|
|
120
|
+
const apiKey = process.env.RESEND_API_KEY;
|
|
121
|
+
if (!apiKey) {
|
|
122
|
+
throw new Error('RESEND_API_KEY environment variable is not set');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
const response = await fetch(`https://api.resend.com/emails/${emailId}`, {
|
|
127
|
+
headers: {
|
|
128
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return await response.json();
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error('Error fetching email status:', error);
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* List sent emails from local history
|
|
145
|
+
* @returns Array of email metadata
|
|
146
|
+
*/
|
|
147
|
+
export function listSentEmails(): Array<any> {
|
|
148
|
+
return Array.from(emailHistory.values());
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Initialize global send_email function for generated API code
|
|
153
|
+
* This makes send_email available in the same way as the preview environment
|
|
154
|
+
*/
|
|
155
|
+
export function initializeGlobalEmailAPI(): void {
|
|
156
|
+
// Make send_email available globally for API code execution
|
|
157
|
+
(global as any).send_email = send_email;
|
|
158
|
+
(global as any).getEmailStatus = getEmailStatus;
|
|
159
|
+
(global as any).listSentEmails = listSentEmails;
|
|
160
|
+
|
|
161
|
+
console.log('✅ Global email API initialized');
|
|
162
|
+
}
|
package/dist/blueprintWriter.js
CHANGED
|
@@ -163,7 +163,21 @@ export async function writeLibraryFile(targetDir, fileType, fileName, base64Data
|
|
|
163
163
|
const fullPath = path.join(targetDir, 'public', libraryPath);
|
|
164
164
|
ensureDir(fullPath);
|
|
165
165
|
// Ensure filename is safe and unique
|
|
166
|
-
|
|
166
|
+
let safeFileName = fileName.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
167
|
+
// Simple approach: Take first 40 chars and add extension
|
|
168
|
+
const nameOnly = safeFileName.substring(0, 40);
|
|
169
|
+
// Add appropriate extension based on file type
|
|
170
|
+
let extension = '';
|
|
171
|
+
if (fileType === 'image') {
|
|
172
|
+
extension = '.jpg';
|
|
173
|
+
}
|
|
174
|
+
else if (fileType === 'video') {
|
|
175
|
+
extension = '.mp4';
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
extension = '.pdf';
|
|
179
|
+
}
|
|
180
|
+
safeFileName = nameOnly + extension;
|
|
167
181
|
const filePath = path.join(fullPath, safeFileName);
|
|
168
182
|
try {
|
|
169
183
|
// Remove data URL prefix if present
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blueprintWriter.js","sourceRoot":"","sources":["../src/blueprintWriter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"blueprintWriter.js","sourceRoot":"","sources":["../src/blueprintWriter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,GAAG,MAAM,kBAAkB,CAAC;AAEnC,uCAAuC;AACvC,KAAK,UAAU,QAAQ,CAAC,OAAe;IACrC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QAC7C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAChG,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC,CAAC;YAChE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;AACH,CAAC;AAoBD,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAAqB,EAAE,OAAqB;IAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,SAAS,CAAC,SAAS,CAAC,CAAC;IAErB,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACpC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjC,MAAM,QAAQ,CAAC,iDAAiD,GAAG,IAAI,CAAC,SAAS,CAAC;QAChF,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS;QACjC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;KACxB,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,QAAQ,CAAC,oEAAoE,CAAC,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,CAAC,qDAAqD,GAAG,IAAI,CAAC,SAAS,CAAC;QACpF,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI;QAC3B,SAAS,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;QACxC,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK;QAC7B,UAAU,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;KAC3C,CAAC,CAAC,CAAC;IAEJ,oDAAoD;IACpD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IAC9C,MAAM,gBAAgB,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IACnF,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACtC,6CAA6C;IAC7C,MAAM,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IACrE,MAAM,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IAC/E,MAAM,0BAA0B,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IAC3F,6FAA6F;IAC7F,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9F,gCAAgC;IAChC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,MAAM,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAC3D,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAEtD,mCAAmC;IACnC,MAAM,oBAAoB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACtD,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAqB,EAAE,OAAqB;IACtF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,SAAS,CAAC,SAAS,CAAC,CAAC;IAErB,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACpC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjC,MAAM,QAAQ,CAAC,+CAA+C,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9E,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC,CAAC;IAEJ,MAAM,QAAQ,CAAC,6CAA6C,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5E,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS;QACjC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;KACxB,CAAC,CAAC,CAAC;IAEJ,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,QAAQ,CAAC,iDAAiD,GAAG,IAAI,CAAC,SAAS,CAAC;YAChF,OAAO,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI;YAC3B,SAAS,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;YACxC,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK;YAC7B,UAAU,EAAE,WAAW,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;SAC3C,CAAC,CAAC,CAAC;IACN,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,CAAC,0DAA0D,CAAC,CAAC;IAC7E,CAAC;IAED,oDAAoD;IACpD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IAC9C,MAAM,gBAAgB,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IACnF,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACtC,6CAA6C;IAC7C,MAAM,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IACrE,MAAM,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE5C,iEAAiE;IACjE,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,EAAE,CAAC;QACnC,MAAM,QAAQ,CAAC,qFAAqF,CAAC,CAAC;QACtG,MAAM,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;QAC/E,MAAM,0BAA0B,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IAC7F,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,CAAC,gEAAgE,GAAG,OAAO,CAAC,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,GAAG,CAAC,CAAC;IAC1I,CAAC;IAED,6FAA6F;IAC7F,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9F,gCAAgC;IAChC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,MAAM,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAC3D,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IAEnD,+EAA+E;IAC/E,MAAM,OAAO,GAAG,WAAW,IAAI,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/E,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;QACjC,MAAM,QAAQ,CAAC,sEAAsE,CAAC,CAAC;QACvF,MAAM,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,CAAC,mDAAmD,GAAG,OAAO,CAAC,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC;IACzH,CAAC;IAED,+DAA+D;AACjE,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAqB,EAAE,OAAqB;IACxF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACpC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAEjC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,oCAAoC;IACpC,MAAM,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,CAAC;IAC7E,MAAM,0BAA0B,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,CAAC;IACzF,MAAM,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAEnD,0DAA0D;IAC1D,MAAM,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AACnD,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,QAAoC,EACpC,QAAgB,EAChB,UAAkB;IAElB,gDAAgD;IAChD,MAAM,YAAY,GAAG;QACnB,OAAO,EAAE,gBAAgB;QACzB,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,eAAe;KACxB,CAAC;IAEF,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC7D,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpB,qCAAqC;IACrC,IAAI,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IAE7D,yDAAyD;IACzD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE/C,+CAA+C;IAC/C,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,SAAS,GAAG,MAAM,CAAC;IACrB,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,SAAS,GAAG,MAAM,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,MAAM,CAAC;IACrB,CAAC;IAED,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,oCAAoC;QACpC,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAElE,0CAA0C;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEtC,MAAM,QAAQ,CAAC,4BAA4B,QAAQ,UAAU,QAAQ,EAAE,CAAC,CAAC;QAEzE,8CAA8C;QAC9C,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,CAAC,oCAAoC,QAAQ,SAAS,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;QAC1F,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/components/form.tsx
CHANGED
|
@@ -9,6 +9,133 @@ interface RFormProps {
|
|
|
9
9
|
design: Design;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
// Translation function for form submit text
|
|
13
|
+
const getFormTranslation = (key: string, websiteLanguage: string) => {
|
|
14
|
+
const translations: Record<string, Record<string, string>> = {
|
|
15
|
+
'Submit': {
|
|
16
|
+
'English': 'Submit',
|
|
17
|
+
'Spanish': 'Enviar',
|
|
18
|
+
'French': 'Soumettre',
|
|
19
|
+
'German': 'Absenden',
|
|
20
|
+
'Portuguese': 'Enviar',
|
|
21
|
+
'Italian': 'Invia',
|
|
22
|
+
'Dutch': 'Versturen',
|
|
23
|
+
'Chinese': '提交',
|
|
24
|
+
'Japanese': '送信',
|
|
25
|
+
'Korean': '제출',
|
|
26
|
+
'Russian': 'Отправить',
|
|
27
|
+
'Arabic': 'إرسال',
|
|
28
|
+
'Hindi': 'सबमिट करें'
|
|
29
|
+
},
|
|
30
|
+
'Submitting...': {
|
|
31
|
+
'English': 'Submitting...',
|
|
32
|
+
'Spanish': 'Enviando...',
|
|
33
|
+
'French': 'Envoi en cours...',
|
|
34
|
+
'German': 'Wird gesendet...',
|
|
35
|
+
'Portuguese': 'Enviando...',
|
|
36
|
+
'Italian': 'Invio in corso...',
|
|
37
|
+
'Dutch': 'Bezig met versturen...',
|
|
38
|
+
'Chinese': '提交中...',
|
|
39
|
+
'Japanese': '送信中...',
|
|
40
|
+
'Korean': '제출 중...',
|
|
41
|
+
'Russian': 'Отправка...',
|
|
42
|
+
'Arabic': 'جاري الإرسال...',
|
|
43
|
+
'Hindi': 'सबमिट हो रहा है...'
|
|
44
|
+
},
|
|
45
|
+
'Submit Another Response': {
|
|
46
|
+
'English': 'Submit Another Response',
|
|
47
|
+
'Spanish': 'Enviar otra respuesta',
|
|
48
|
+
'French': 'Soumettre une autre réponse',
|
|
49
|
+
'German': 'Weitere Antwort senden',
|
|
50
|
+
'Portuguese': 'Enviar outra resposta',
|
|
51
|
+
'Italian': 'Invia un\'altra risposta',
|
|
52
|
+
'Dutch': 'Nog een reactie versturen',
|
|
53
|
+
'Chinese': '提交另一个回复',
|
|
54
|
+
'Japanese': '別の回答を送信',
|
|
55
|
+
'Korean': '다른 응답 제출',
|
|
56
|
+
'Russian': 'Отправить еще один ответ',
|
|
57
|
+
'Arabic': 'إرسال رد آخر',
|
|
58
|
+
'Hindi': 'एक और प्रतिक्रिया सबमिट करें'
|
|
59
|
+
},
|
|
60
|
+
'Thank You!': {
|
|
61
|
+
'English': 'Thank You!',
|
|
62
|
+
'Spanish': '¡Gracias!',
|
|
63
|
+
'French': 'Merci!',
|
|
64
|
+
'German': 'Vielen Dank!',
|
|
65
|
+
'Portuguese': 'Obrigado!',
|
|
66
|
+
'Italian': 'Grazie!',
|
|
67
|
+
'Dutch': 'Bedankt!',
|
|
68
|
+
'Chinese': '谢谢!',
|
|
69
|
+
'Japanese': 'ありがとうございます!',
|
|
70
|
+
'Korean': '감사합니다!',
|
|
71
|
+
'Russian': 'Спасибо!',
|
|
72
|
+
'Arabic': 'شكراً لك!',
|
|
73
|
+
'Hindi': 'धन्यवाद!'
|
|
74
|
+
},
|
|
75
|
+
'Your form has been submitted successfully. We\'ll get back to you soon.': {
|
|
76
|
+
'English': 'Your form has been submitted successfully. We\'ll get back to you soon.',
|
|
77
|
+
'Spanish': 'Tu formulario ha sido enviado exitosamente. Nos pondremos en contacto contigo pronto.',
|
|
78
|
+
'French': 'Votre formulaire a été soumis avec succès. Nous vous contacterons bientôt.',
|
|
79
|
+
'German': 'Ihr Formular wurde erfolgreich gesendet. Wir werden uns bald bei Ihnen melden.',
|
|
80
|
+
'Portuguese': 'Seu formulário foi enviado com sucesso. Entraremos em contato em breve.',
|
|
81
|
+
'Italian': 'Il tuo modulo è stato inviato con successo. Ti contatteremo presto.',
|
|
82
|
+
'Dutch': 'Uw formulier is succesvol verzonden. We nemen binnenkort contact met u op.',
|
|
83
|
+
'Chinese': '您的表单已成功提交。我们会尽快与您联系。',
|
|
84
|
+
'Japanese': 'フォームが正常に送信されました。近日中にご連絡いたします。',
|
|
85
|
+
'Korean': '양식이 성공적으로 제출되었습니다. 곧 연락드리겠습니다.',
|
|
86
|
+
'Russian': 'Ваша форма успешно отправлена. Мы свяжемся с вами в ближайшее время.',
|
|
87
|
+
'Arabic': 'تم إرسال النموذج بنجاح. سنتواصل معك قريباً.',
|
|
88
|
+
'Hindi': 'आपका फॉर्म सफलतापूर्वक सबमिट किया गया है। हम जल्द ही आपसे संपर्क करेंगे।'
|
|
89
|
+
},
|
|
90
|
+
'Form secured by FormSubmit': {
|
|
91
|
+
'English': 'Form secured by FormSubmit',
|
|
92
|
+
'Spanish': 'Formulario protegido por FormSubmit',
|
|
93
|
+
'French': 'Formulaire sécurisé par FormSubmit',
|
|
94
|
+
'German': 'Formular gesichert durch FormSubmit',
|
|
95
|
+
'Portuguese': 'Formulário protegido por FormSubmit',
|
|
96
|
+
'Italian': 'Modulo protetto da FormSubmit',
|
|
97
|
+
'Dutch': 'Formulier beveiligd door FormSubmit',
|
|
98
|
+
'Chinese': '表单由FormSubmit保护',
|
|
99
|
+
'Japanese': 'FormSubmitによって保護されたフォーム',
|
|
100
|
+
'Korean': 'FormSubmit로 보호된 양식',
|
|
101
|
+
'Russian': 'Форма защищена FormSubmit',
|
|
102
|
+
'Arabic': 'النموذج محمي بواسطة FormSubmit',
|
|
103
|
+
'Hindi': 'फॉर्म FormSubmit द्वारा सुरक्षित'
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Determine which language to use
|
|
108
|
+
let language = 'English'; // Default
|
|
109
|
+
if (websiteLanguage) {
|
|
110
|
+
// Extract the main language from the input
|
|
111
|
+
const langMap: Record<string, string> = {
|
|
112
|
+
'English': 'English',
|
|
113
|
+
'Spanish': 'Spanish',
|
|
114
|
+
'French': 'French',
|
|
115
|
+
'German': 'German',
|
|
116
|
+
'Portuguese': 'Portuguese',
|
|
117
|
+
'Italian': 'Italian',
|
|
118
|
+
'Dutch': 'Dutch',
|
|
119
|
+
'Chinese': 'Chinese',
|
|
120
|
+
'Japanese': 'Japanese',
|
|
121
|
+
'Korean': 'Korean',
|
|
122
|
+
'Russian': 'Russian',
|
|
123
|
+
'Arabic': 'Arabic',
|
|
124
|
+
'Hindi': 'Hindi'
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Find the matching language
|
|
128
|
+
for (const [langKey, langValue] of Object.entries(langMap)) {
|
|
129
|
+
if (websiteLanguage.includes(langKey)) {
|
|
130
|
+
language = langValue;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return translations[key]?.[language] || key;
|
|
137
|
+
};
|
|
138
|
+
|
|
12
139
|
interface FormField {
|
|
13
140
|
id: string;
|
|
14
141
|
name: string;
|
|
@@ -85,9 +212,9 @@ export default function RForm({ name, custom_view_description, design }: RFormPr
|
|
|
85
212
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
86
213
|
/>
|
|
87
214
|
</svg>
|
|
88
|
-
<h3 className="text-2xl font-bold text-green-800 mb-2">Thank You
|
|
215
|
+
<h3 className="text-2xl font-bold text-green-800 mb-2">{getFormTranslation('Thank You!', design.websiteLanguage)}</h3>
|
|
89
216
|
<p className="text-green-700">
|
|
90
|
-
Your form has been submitted successfully. We'll get back to you soon.
|
|
217
|
+
{getFormTranslation('Your form has been submitted successfully. We\'ll get back to you soon.', design.websiteLanguage)}
|
|
91
218
|
</p>
|
|
92
219
|
<button
|
|
93
220
|
onClick={() => {
|
|
@@ -97,7 +224,7 @@ export default function RForm({ name, custom_view_description, design }: RFormPr
|
|
|
97
224
|
}}
|
|
98
225
|
className="mt-6 px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
|
|
99
226
|
>
|
|
100
|
-
Submit Another Response
|
|
227
|
+
{getFormTranslation('Submit Another Response', design.websiteLanguage)}
|
|
101
228
|
</button>
|
|
102
229
|
</div>
|
|
103
230
|
</div>
|
|
@@ -249,10 +376,10 @@ export default function RForm({ name, custom_view_description, design }: RFormPr
|
|
|
249
376
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
250
377
|
/>
|
|
251
378
|
</svg>
|
|
252
|
-
Submitting...
|
|
379
|
+
{getFormTranslation('Submitting...', design.websiteLanguage)}
|
|
253
380
|
</span>
|
|
254
381
|
) : (
|
|
255
|
-
'Submit'
|
|
382
|
+
getFormTranslation('Submit', design.websiteLanguage)
|
|
256
383
|
)}
|
|
257
384
|
</button>
|
|
258
385
|
</div>
|
|
@@ -260,7 +387,7 @@ export default function RForm({ name, custom_view_description, design }: RFormPr
|
|
|
260
387
|
|
|
261
388
|
{/* FormSubmit.co attribution (optional but nice to have) */}
|
|
262
389
|
<div className="mt-6 text-center text-xs text-gray-400">
|
|
263
|
-
<p>Form secured by FormSubmit</p>
|
|
390
|
+
<p>{getFormTranslation('Form secured by FormSubmit', design.websiteLanguage)}</p>
|
|
264
391
|
</div>
|
|
265
392
|
</div>
|
|
266
393
|
);
|
|
@@ -9,11 +9,17 @@ checked in the system build settings. It is safe to modify this file without it
|
|
|
9
9
|
import React, { useState } from 'react';
|
|
10
10
|
|
|
11
11
|
interface LoginProps {
|
|
12
|
-
providers: ('apple' | 'facebook' | 'github' | 'google')[];
|
|
12
|
+
providers: ('apple' | 'facebook' | 'github' | 'google' | 'username')[];
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export default function Login({ providers }: LoginProps) {
|
|
16
16
|
const [error, setError] = useState<string | null>(null);
|
|
17
|
+
const [isSignup, setIsSignup] = useState(false);
|
|
18
|
+
const [email, setEmail] = useState('');
|
|
19
|
+
const [password, setPassword] = useState('');
|
|
20
|
+
const [confirmPassword, setConfirmPassword] = useState('');
|
|
21
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
22
|
+
const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
|
|
17
23
|
|
|
18
24
|
|
|
19
25
|
const handleProviderLogin = async (provider: string) => {
|
|
@@ -43,37 +49,183 @@ export default function Login({ providers }: LoginProps) {
|
|
|
43
49
|
|
|
44
50
|
};
|
|
45
51
|
|
|
52
|
+
const handleUsernamePasswordAuth = async (e: React.FormEvent) => {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
setError(null);
|
|
55
|
+
setMessage(null);
|
|
56
|
+
setIsLoading(true);
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
if (isSignup) {
|
|
60
|
+
// Handle signup
|
|
61
|
+
if (password !== confirmPassword) {
|
|
62
|
+
setError('Passwords do not match');
|
|
63
|
+
setIsLoading(false);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const response = await fetch('/api/Auth/signup', {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: { 'Content-Type': 'application/json' },
|
|
70
|
+
body: JSON.stringify({ email, password })
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const data = await response.json();
|
|
74
|
+
|
|
75
|
+
if (response.ok) {
|
|
76
|
+
setMessage({ type: 'success', text: 'Verification email sent! Please check your inbox.' });
|
|
77
|
+
setIsSignup(false);
|
|
78
|
+
setPassword('');
|
|
79
|
+
setConfirmPassword('');
|
|
80
|
+
} else {
|
|
81
|
+
setError(data.error || 'Signup failed');
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
// Handle login
|
|
85
|
+
const response = await fetch('/api/Auth', {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
body: JSON.stringify({ email, password, provider: 'username' })
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const data = await response.json();
|
|
92
|
+
|
|
93
|
+
if (response.ok) {
|
|
94
|
+
// Redirect to home or dashboard
|
|
95
|
+
window.location.href = '/';
|
|
96
|
+
} else {
|
|
97
|
+
setError(data.error || 'Login failed');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} catch (err) {
|
|
101
|
+
setError('An unexpected error occurred');
|
|
102
|
+
} finally {
|
|
103
|
+
setIsLoading(false);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const showUsernamePasswordForm = providers?.includes('username');
|
|
108
|
+
const oauthProviders = providers?.filter(p => p !== 'username') || [];
|
|
109
|
+
|
|
46
110
|
return (
|
|
47
111
|
<div className="flex flex-col items-center justify-center min-h-[500px] p-4">
|
|
48
112
|
<div className="w-full max-w-md space-y-8">
|
|
49
113
|
<div className="text-center">
|
|
50
|
-
<h2 className="text-3xl font-bold">Sign in to your account</h2>
|
|
114
|
+
<h2 className="text-3xl font-bold">{isSignup ? 'Create an account' : 'Sign in to your account'}</h2>
|
|
51
115
|
</div>
|
|
52
116
|
|
|
53
|
-
{(
|
|
54
|
-
<
|
|
55
|
-
<div className="
|
|
56
|
-
<div
|
|
57
|
-
<
|
|
117
|
+
{showUsernamePasswordForm && (
|
|
118
|
+
<form onSubmit={handleUsernamePasswordAuth} className="mt-8 space-y-6">
|
|
119
|
+
<div className="space-y-4">
|
|
120
|
+
<div>
|
|
121
|
+
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
|
|
122
|
+
Email address
|
|
123
|
+
</label>
|
|
124
|
+
<input
|
|
125
|
+
id="email"
|
|
126
|
+
name="email"
|
|
127
|
+
type="email"
|
|
128
|
+
autoComplete="email"
|
|
129
|
+
required
|
|
130
|
+
value={email}
|
|
131
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
132
|
+
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
|
|
133
|
+
/>
|
|
58
134
|
</div>
|
|
59
|
-
|
|
60
|
-
|
|
135
|
+
|
|
136
|
+
<div>
|
|
137
|
+
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
|
|
138
|
+
Password
|
|
139
|
+
</label>
|
|
140
|
+
<input
|
|
141
|
+
id="password"
|
|
142
|
+
name="password"
|
|
143
|
+
type="password"
|
|
144
|
+
autoComplete={isSignup ? 'new-password' : 'current-password'}
|
|
145
|
+
required
|
|
146
|
+
value={password}
|
|
147
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
148
|
+
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
|
|
149
|
+
/>
|
|
61
150
|
</div>
|
|
62
|
-
</div>
|
|
63
151
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
152
|
+
{isSignup && (
|
|
153
|
+
<div>
|
|
154
|
+
<label htmlFor="confirmPassword" className="block text-sm font-medium text-gray-700">
|
|
155
|
+
Confirm Password
|
|
156
|
+
</label>
|
|
157
|
+
<input
|
|
158
|
+
id="confirmPassword"
|
|
159
|
+
name="confirmPassword"
|
|
160
|
+
type="password"
|
|
161
|
+
autoComplete="new-password"
|
|
162
|
+
required
|
|
163
|
+
value={confirmPassword}
|
|
164
|
+
onChange={(e) => setConfirmPassword(e.target.value)}
|
|
165
|
+
className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
75
168
|
)}
|
|
76
169
|
</div>
|
|
170
|
+
|
|
171
|
+
<div>
|
|
172
|
+
<button
|
|
173
|
+
type="submit"
|
|
174
|
+
disabled={isLoading}
|
|
175
|
+
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
|
176
|
+
>
|
|
177
|
+
{isLoading ? 'Processing...' : (isSignup ? 'Sign up' : 'Sign in')}
|
|
178
|
+
</button>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div className="text-center">
|
|
182
|
+
<button
|
|
183
|
+
type="button"
|
|
184
|
+
onClick={() => {
|
|
185
|
+
setIsSignup(!isSignup);
|
|
186
|
+
setError(null);
|
|
187
|
+
setMessage(null);
|
|
188
|
+
}}
|
|
189
|
+
className="text-sm text-indigo-600 hover:text-indigo-500"
|
|
190
|
+
>
|
|
191
|
+
{isSignup ? 'Already have an account? Sign in' : "Don't have an account? Sign up"}
|
|
192
|
+
</button>
|
|
193
|
+
</div>
|
|
194
|
+
</form>
|
|
195
|
+
)}
|
|
196
|
+
|
|
197
|
+
{oauthProviders.length > 0 && (
|
|
198
|
+
<div className="mt-6">
|
|
199
|
+
{showUsernamePasswordForm && (
|
|
200
|
+
<>
|
|
201
|
+
<div className="relative">
|
|
202
|
+
<div className="absolute inset-0 flex items-center">
|
|
203
|
+
<div className="w-full border-t"></div>
|
|
204
|
+
</div>
|
|
205
|
+
<div className="relative flex justify-center text-sm">
|
|
206
|
+
<span className="px-2 bg-white text-gray-500">Or continue with</span>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
</>
|
|
210
|
+
)}
|
|
211
|
+
|
|
212
|
+
<div className={`mt-6 grid grid-cols-${Math.min(oauthProviders.length, 2)} gap-3`}>
|
|
213
|
+
{oauthProviders.map(provider => (
|
|
214
|
+
<button
|
|
215
|
+
key={provider}
|
|
216
|
+
onClick={() => handleProviderLogin(provider)}
|
|
217
|
+
className="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 transition duration-150 classButtonRounding classButtonBackground classButtonFontType classButtonFontSize"
|
|
218
|
+
>
|
|
219
|
+
{provider}
|
|
220
|
+
</button>
|
|
221
|
+
))}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
)}
|
|
225
|
+
|
|
226
|
+
{message && (
|
|
227
|
+
<div className={`mt-4 text-center ${message.type === 'success' ? 'text-green-600' : 'text-red-600'}`}>
|
|
228
|
+
{message.text}
|
|
77
229
|
</div>
|
|
78
230
|
)}
|
|
79
231
|
|