mirror of
https://github.com/tavo-wasd-gh/conex-builder.git
synced 2025-07-13 10:33:30 -06:00
ui title and craft client request body
This commit is contained in:
parent
ec5a3be6fb
commit
28b7b1802c
7 changed files with 270 additions and 31 deletions
128
public/client.js
128
public/client.js
|
@ -1,4 +1,13 @@
|
|||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const savedData = localStorage.getItem('editor_data');
|
||||
if (savedData) {
|
||||
const parsedData = JSON.parse(savedData);
|
||||
console.log('Loaded parsedData:', parsedData);
|
||||
document.getElementById('title').value = parsedData.title || '';
|
||||
document.getElementById('slogan').value = parsedData.slogan || '';
|
||||
document.getElementById('banner').src = parsedData.banner || '/static/svg/banner.svg';
|
||||
}
|
||||
|
||||
const dialog = document.getElementById("dialog");
|
||||
const overlay = document.getElementById("overlay");
|
||||
const menu = document.getElementById("floatingButtons");
|
||||
|
@ -17,4 +26,123 @@ document.addEventListener("DOMContentLoaded", function() {
|
|||
|
||||
document.getElementById("openDialogButton").addEventListener("click", openDialog);
|
||||
document.getElementById("cancelDialogButton").addEventListener("click", closeDialog);
|
||||
document.getElementById('title').addEventListener('change', saveEditorData);
|
||||
document.getElementById('slogan').addEventListener('change', saveEditorData);
|
||||
});
|
||||
|
||||
function saveEditorData() {
|
||||
const banner = document.getElementById('banner').src;
|
||||
const title = document.getElementById('title').value;
|
||||
const slogan = document.getElementById('slogan').value;
|
||||
|
||||
editor.save().then((editor_data) => {
|
||||
const dataToSave = {
|
||||
banner: banner,
|
||||
title: title,
|
||||
slogan: slogan,
|
||||
editor_data: editor_data
|
||||
};
|
||||
localStorage.setItem('editor_data', JSON.stringify(dataToSave));
|
||||
console.log('Editor data saved to localStorage');
|
||||
}).catch((error) => {
|
||||
console.error('Saving failed:', error);
|
||||
});
|
||||
}
|
||||
|
||||
const directoryInput = document.getElementById('title');
|
||||
const statusPopup = document.getElementById('status-popup');
|
||||
const statusMessage = document.getElementById('status-message');
|
||||
|
||||
let typingTimeout;
|
||||
let hideTimeout;
|
||||
|
||||
directoryInput.addEventListener('input', () => {
|
||||
clearTimeout(typingTimeout);
|
||||
typingTimeout = setTimeout(() => {
|
||||
const directoryName = directoryInput.value.trim();
|
||||
if (directoryName.length > 0) {
|
||||
const sanitizedDirectoryName = sanitizeDirectoryName(directoryName);
|
||||
checkDirectory(sanitizedDirectoryName);
|
||||
} else {
|
||||
hidePopup();
|
||||
}
|
||||
}, 500); // Debounce
|
||||
});
|
||||
|
||||
function sanitizeDirectoryName(name) {
|
||||
return name
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-z0-9\-]/g, '');
|
||||
}
|
||||
|
||||
function checkDirectory(name) {
|
||||
if (name.length < 4) {
|
||||
return;
|
||||
}
|
||||
fetch(`/api/directory/${encodeURIComponent(name)}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.exists) {
|
||||
showPopup(`El sitio web conex.one/${name} ya existe`, 'exists');
|
||||
} else {
|
||||
showPopup(`Se publicará en conex.one/${name}`, 'available');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error checking directory:', error);
|
||||
showPopup('Error checking directory.', 'exists');
|
||||
});
|
||||
}
|
||||
|
||||
function showPopup(message, status) {
|
||||
const popup = document.querySelector('.status-popup');
|
||||
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout);
|
||||
}
|
||||
|
||||
const existingCloseButton = popup.querySelector('.close-popup');
|
||||
if (existingCloseButton) {
|
||||
existingCloseButton.remove();
|
||||
}
|
||||
|
||||
const closeButton = document.createElement('span');
|
||||
closeButton.classList.add('close-popup');
|
||||
closeButton.innerHTML = '×';
|
||||
closeButton.addEventListener('click', () => {
|
||||
hidePopup(popup, status);
|
||||
});
|
||||
|
||||
popup.innerHTML = message;
|
||||
popup.appendChild(closeButton);
|
||||
popup.classList.remove('exists', 'available');
|
||||
popup.classList.add(status);
|
||||
popup.classList.add('show');
|
||||
|
||||
hideTimeout = setTimeout(() => {
|
||||
hidePopup(popup, status);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
function hidePopup(popup, status) {
|
||||
popup.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
popup.classList.remove(status);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.getElementById('imageUpload').addEventListener('change', function (event) {
|
||||
const file = event.target.files[0];
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
const base64Image = e.target.result;
|
||||
document.getElementById('banner').src = base64Image;
|
||||
saveEditorData();
|
||||
};
|
||||
|
||||
if (file) {
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,19 +10,20 @@
|
|||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<link rel="stylesheet" href="/static/css/editorjs-dark.css">
|
||||
<script src="/client.js"></script>
|
||||
</head>
|
||||
<!-- <div class="banner" style="background-image: url(/static/svg/banner.svg);"> -->
|
||||
<!-- <div class="desc"> -->
|
||||
<!-- <input type="text" name="title" class="input-title" placeholder="[Nombre Ejemplo]"> -->
|
||||
<!-- <input type="text" name="slogan" class="input-slogan" placeholder="[Slogan llamativo o breve descripción]"> -->
|
||||
<!-- </div> -->
|
||||
<!-- </div> -->
|
||||
<div class="banner">
|
||||
<img src="/static/svg/banner.svg" class="banner-image"/>
|
||||
<input type="file" id="imageUpload" accept="image/*">
|
||||
<label for="imageUpload" class="upload-button">
|
||||
<img src="/static/svg/edit.svg" alt="Edit Icon" class="icon">
|
||||
</label>
|
||||
<img id="banner" name="banner" src="/static/svg/banner.svg" class="banner-image"/>
|
||||
<div class="desc">
|
||||
<input type="text" name="title" class="input-title" placeholder="[Nombre Ejemplo]">
|
||||
<input type="text" name="slogan" class="input-slogan" placeholder="[Slogan llamativo o breve descripción]">
|
||||
<input type="text" id="title" name="title" class="input-title" placeholder="[Nombre Ejemplo]">
|
||||
<input type="text" id="slogan" name="slogan" class="input-slogan" placeholder="[Slogan llamativo o breve descripción]">
|
||||
</div>
|
||||
<div id="status-popup" class="status-popup">
|
||||
<span class="close-popup" onclick="hidePopup()">×</span>
|
||||
<span id="status-message"></span>
|
||||
</div>
|
||||
</div>
|
||||
<body>
|
||||
|
@ -60,6 +61,7 @@
|
|||
</picture>
|
||||
</button>
|
||||
</div>
|
||||
<script src="/client.js"></script>
|
||||
<script src="https://sandbox.paypal.com/sdk/js?client-id=AcCW43LI1S6lLQgtLkF4V8UOPfmXcqXQ8xfEl41hRuMxSskR2jkWNwQN6Ab1WK7E2E52GNaoYBHqgIKd&components=buttons&enable-funding=card&disable-funding=paylater,venmo"></script>
|
||||
<script src="/paypal.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script><!-- Header -->
|
||||
|
|
|
@ -6,9 +6,13 @@ paypal.Buttons({
|
|||
label: "pay"
|
||||
},
|
||||
async createOrder() {
|
||||
const savedData = JSON.parse(localStorage.getItem('editor_data')) || {};
|
||||
const requestData = {
|
||||
directory: "gofitness",
|
||||
editor_data: await editor.save()
|
||||
directory: sanitizeDirectoryName(savedData.title),
|
||||
banner: savedData.banner || '/static/svg/banner.svg',
|
||||
title: savedData.title,
|
||||
slogan: savedData.slogan,
|
||||
editor_data: savedData.editor_data
|
||||
};
|
||||
const response = await fetch("/api/orders", {
|
||||
method: "POST",
|
||||
|
@ -20,7 +24,7 @@ paypal.Buttons({
|
|||
|
||||
if (!response.ok) {
|
||||
if (response.status === 409) {
|
||||
resultMessage(`No se puede comprar este sitio, ya existe. Prueba con un nombre diferente`);
|
||||
resultMessage(`No se puede comprar este sitio, ya existe o tiene un nombre incorrecto. Prueba con un nombre diferente`);
|
||||
} else {
|
||||
resultMessage(`No se puede realizar la compra en este momento`);
|
||||
}
|
||||
|
@ -39,6 +43,7 @@ paypal.Buttons({
|
|||
},
|
||||
async onApprove(data, actions) {
|
||||
try {
|
||||
// @@@ TODO por alguna razon hizo la compra a pesar de que esto estaba mal puesto
|
||||
const requestData = {
|
||||
directory: "gofitness",
|
||||
editor_data: await editor.save()
|
||||
|
|
|
@ -313,3 +313,72 @@ button {
|
|||
background: linear-gradient(135deg, #21532a, #4fc764);
|
||||
box-shadow: #27d100 0 10px 20px -15px;
|
||||
}
|
||||
|
||||
.status-popup {
|
||||
position: fixed;
|
||||
top: 19%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
background-color: #f0f0f0;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.1s ease, visibility 0.1s ease;
|
||||
}
|
||||
|
||||
.status-popup.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.status-popup.exists {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.status-popup.available {
|
||||
background-color: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.close-popup {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
right: 5px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#imageUpload {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-button {
|
||||
position: fixed;
|
||||
top: 2%;
|
||||
left: 2%;
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--hover-border);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: background-color 0.2s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upload-button:hover {
|
||||
background-color: #ffffff40; /* Hover effect */
|
||||
}
|
||||
|
||||
.upload-button .icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
const savedData = localStorage.getItem('editor_data');
|
||||
const parsedData = savedData ? JSON.parse(savedData) : null;
|
||||
|
||||
const editor = new EditorJS({
|
||||
// readOnly: false,
|
||||
holder: 'editorjs',
|
||||
|
@ -73,7 +76,7 @@ const editor = new EditorJS({
|
|||
},
|
||||
},
|
||||
|
||||
data: {
|
||||
data: parsedData ? parsedData.editor_data : {
|
||||
blocks: [
|
||||
{
|
||||
type: "header",
|
||||
|
@ -188,7 +191,7 @@ const editor = new EditorJS({
|
|||
}
|
||||
},
|
||||
onChange: function(api, event) {
|
||||
console.log('something changed', event);
|
||||
saveEditorData();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ const (
|
|||
)
|
||||
|
||||
func AvailableSite(folder string) error {
|
||||
if len(folder) <= 3 {
|
||||
return fmt.Errorf("folder name must be longer than 3 characters")
|
||||
}
|
||||
|
||||
var exists bool
|
||||
if err := db.QueryRow(`
|
||||
SELECT EXISTS(SELECT * FROM sites WHERE folder = $1)
|
||||
|
|
|
@ -34,6 +34,7 @@ func main() {
|
|||
http.HandleFunc("/api/orders/", CaptureOrderHandler)
|
||||
http.HandleFunc("/api/update", UpdateSiteHandler)
|
||||
http.HandleFunc("/api/confirm", ConfirmChangesHandler)
|
||||
http.HandleFunc("/api/directory/", VerifyDirectoryHandler)
|
||||
http.Handle("/", http.FileServer(http.Dir("./public")))
|
||||
|
||||
stop := make(chan os.Signal, 1)
|
||||
|
@ -192,3 +193,30 @@ func ConfirmChangesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
func VerifyDirectoryHandler(w http.ResponseWriter, r *http.Request) {
|
||||
errClientNotice := "Error verifying directory against db"
|
||||
|
||||
path := strings.TrimPrefix(r.URL.Path, "/api/directory/")
|
||||
parts := strings.Split(path, "/")
|
||||
folder := parts[0]
|
||||
if folder == "" {
|
||||
httpErrorAndLog(w, nil, "Error getting directory", errClientNotice)
|
||||
return
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Exists bool `json:"exists"`
|
||||
}
|
||||
|
||||
err := AvailableSite(folder)
|
||||
if err != nil {
|
||||
response.Exists = true
|
||||
} else {
|
||||
response.Exists = false
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue