feat: complete node task 2a
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const sendBtn = document.getElementById("send-btn");
|
||||
const messageList = document.getElementById("message-list");
|
||||
const saveBtn = document.getElementById("save-btn");
|
||||
const chatMessages = document.getElementById("chat-messages");
|
||||
|
||||
let lastMessageCount = 0;
|
||||
|
||||
// Send message
|
||||
async function sendMessage() {
|
||||
const message = messageInput.value.trim();
|
||||
if (!message) return;
|
||||
|
||||
try {
|
||||
const response = await fetch("/send", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ message }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
messageInput.value = "";
|
||||
await fetchMessages();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to send message:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch all messages
|
||||
async function fetchMessages() {
|
||||
try {
|
||||
const response = await fetch("/chat/all");
|
||||
const messages = await response.json();
|
||||
|
||||
messageList.innerHTML = "";
|
||||
messages.forEach((msg) => {
|
||||
const li = document.createElement("li");
|
||||
li.className = "p-2 bg-gray-100 rounded";
|
||||
li.innerHTML = `
|
||||
<div class="text-sm text-gray-600">${new Date(
|
||||
msg.timestamp
|
||||
).toLocaleString()}</div>
|
||||
<div class="font-medium">${msg.message}</div>
|
||||
`;
|
||||
messageList.appendChild(li);
|
||||
});
|
||||
|
||||
// Auto-scroll to bottom
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
lastMessageCount = messages.length;
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch messages:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Poll for updates
|
||||
async function pollForUpdates() {
|
||||
try {
|
||||
const response = await fetch(`/poll?lastCheck=${lastMessageCount}`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.updated) {
|
||||
await fetchMessages();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Poll failed:", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Save chat
|
||||
async function saveChat() {
|
||||
try {
|
||||
const response = await fetch("/chat/save", { method: "POST" });
|
||||
if (response.ok) {
|
||||
alert("Chat saved successfully!");
|
||||
} else {
|
||||
alert("Failed to save chat");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to save chat:", err);
|
||||
alert("Failed to save chat");
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
sendBtn.addEventListener("click", sendMessage);
|
||||
messageInput.addEventListener("keypress", (e) => {
|
||||
if (e.key === "Enter") sendMessage();
|
||||
});
|
||||
saveBtn.addEventListener("click", saveChat);
|
||||
|
||||
// Initial load and start polling
|
||||
fetchMessages();
|
||||
setInterval(pollForUpdates, 2000);
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
// DOM elements
|
||||
const createFlowBtn = document.getElementById("create-flow-btn");
|
||||
const flowNameInput = document.getElementById("flow-name");
|
||||
const flowDescriptionInput = document.getElementById("flow-description");
|
||||
const flowSelect = document.getElementById("flow-select");
|
||||
const actionTypeSelect = document.getElementById("action-type");
|
||||
const taskInput = document.getElementById("task-input");
|
||||
const orderIndexInput = document.getElementById("order-index");
|
||||
const addTaskBtn = document.getElementById("add-task-btn");
|
||||
const flowDetails = document.getElementById("flow-details");
|
||||
const executeFlowSelect = document.getElementById("execute-flow-select");
|
||||
const executePayloadInput = document.getElementById("execute-payload");
|
||||
const executeBtn = document.getElementById("execute-btn");
|
||||
const webhookBtn = document.getElementById("webhook-btn");
|
||||
const executionResults = document.getElementById("execution-results");
|
||||
|
||||
let currentFlows = [];
|
||||
|
||||
// Create new flow
|
||||
async function createFlow() {
|
||||
const name = flowNameInput.value.trim();
|
||||
const description = flowDescriptionInput.value.trim();
|
||||
|
||||
if (!name) {
|
||||
alert("Flow name is required");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/flow", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ name, description }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const flow = await response.json();
|
||||
alert(`Flow "${flow.name}" created successfully!`);
|
||||
flowNameInput.value = "";
|
||||
flowDescriptionInput.value = "";
|
||||
loadFlows();
|
||||
} else {
|
||||
const error = await response.json();
|
||||
alert(`Error: ${error.error}`);
|
||||
}
|
||||
} catch (err) {
|
||||
alert("Failed to create flow");
|
||||
}
|
||||
}
|
||||
|
||||
// Load all flows
|
||||
async function loadFlows() {
|
||||
try {
|
||||
const response = await fetch("/flows");
|
||||
const flows = await response.json();
|
||||
currentFlows = flows;
|
||||
|
||||
// Update flow selects
|
||||
flowSelect.innerHTML = '<option value="">Select Flow</option>';
|
||||
executeFlowSelect.innerHTML =
|
||||
'<option value="">Select Flow to Execute</option>';
|
||||
|
||||
flows.forEach((flow) => {
|
||||
flowSelect.innerHTML += `<option value="${flow.id}">${flow.name}</option>`;
|
||||
executeFlowSelect.innerHTML += `<option value="${flow.id}">${flow.name}</option>`;
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Failed to load flows");
|
||||
}
|
||||
}
|
||||
|
||||
// Add task to flow
|
||||
async function addTask() {
|
||||
const flowId = flowSelect.value;
|
||||
const actionType = actionTypeSelect.value;
|
||||
const inputData = taskInput.value.trim();
|
||||
const orderIndex = parseInt(orderIndexInput.value);
|
||||
|
||||
if (!flowId || !actionType || !inputData || isNaN(orderIndex)) {
|
||||
alert("All fields are required");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/flow/${flowId}/task`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
action_type: actionType,
|
||||
input_data: inputData,
|
||||
order_index: orderIndex,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const task = await response.json();
|
||||
alert(`Task "${task.action_type}" added successfully!`);
|
||||
taskInput.value = "";
|
||||
orderIndexInput.value = "";
|
||||
loadFlowDetails(flowId);
|
||||
} else {
|
||||
const error = await response.json();
|
||||
alert(`Error: ${error.error}`);
|
||||
}
|
||||
} catch (err) {
|
||||
alert("Failed to add task");
|
||||
}
|
||||
}
|
||||
|
||||
// Load flow details
|
||||
async function loadFlowDetails(flowId) {
|
||||
if (!flowId) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`/flow/${flowId}`);
|
||||
const data = await response.json();
|
||||
|
||||
flowDetails.innerHTML = `
|
||||
<div class="border rounded p-4">
|
||||
<h3 class="font-semibold text-lg">${data.flow.name}</h3>
|
||||
<p class="text-gray-600">${
|
||||
data.flow.description || "No description"
|
||||
}</p>
|
||||
<div class="mt-4">
|
||||
<h4 class="font-medium">Tasks:</h4>
|
||||
<div class="space-y-2 mt-2">
|
||||
${data.tasks
|
||||
.map(
|
||||
(task) => `
|
||||
<div class="bg-gray-100 p-2 rounded">
|
||||
<div class="font-medium">${task.action_type}</div>
|
||||
<div class="text-sm text-gray-600">Input: ${task.input_data}</div>
|
||||
<div class="text-xs text-gray-500">Order: ${task.order_index}</div>
|
||||
</div>
|
||||
`
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} catch (err) {
|
||||
console.error("Failed to load flow details");
|
||||
}
|
||||
}
|
||||
|
||||
// Execute flow
|
||||
async function executeFlow() {
|
||||
const flowId = executeFlowSelect.value;
|
||||
const payload = executePayloadInput.value.trim();
|
||||
|
||||
if (!flowId) {
|
||||
alert("Please select a flow to execute");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/flow/${flowId}/execute`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ payload }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
showExecutionResults(result);
|
||||
} else {
|
||||
const error = await response.json();
|
||||
alert(`Error: ${error.error}`);
|
||||
}
|
||||
} catch (err) {
|
||||
alert("Failed to execute flow");
|
||||
}
|
||||
}
|
||||
|
||||
// Show execution results
|
||||
function showExecutionResults(result) {
|
||||
executionResults.innerHTML = `
|
||||
<h4 class="font-semibold mb-2">Execution Results:</h4>
|
||||
<div class="space-y-2">
|
||||
${result.results
|
||||
.map(
|
||||
(r) => `
|
||||
<div class="p-2 ${
|
||||
r.status === "success" ? "bg-green-100" : "bg-red-100"
|
||||
} rounded">
|
||||
<div class="font-medium">Task ${r.task_id}</div>
|
||||
<div class="text-sm">${r.result}</div>
|
||||
<div class="text-xs text-gray-600">Status: ${r.status}</div>
|
||||
</div>
|
||||
`
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
`;
|
||||
executionResults.classList.remove("hidden");
|
||||
}
|
||||
|
||||
// Get webhook URL
|
||||
function getWebhookUrl() {
|
||||
const flowId = executeFlowSelect.value;
|
||||
|
||||
if (!flowId) {
|
||||
alert("Please select a flow");
|
||||
return;
|
||||
}
|
||||
|
||||
const webhookUrl = `${window.location.origin}/flow/${flowId}/trigger?payload=test@example.com`;
|
||||
alert(
|
||||
`Webhook URL:\n${webhookUrl}\n\nCopy this URL to trigger the flow via webhook.`
|
||||
);
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
createFlowBtn.addEventListener("click", createFlow);
|
||||
addTaskBtn.addEventListener("click", addTask);
|
||||
executeBtn.addEventListener("click", executeFlow);
|
||||
webhookBtn.addEventListener("click", getWebhookUrl);
|
||||
|
||||
flowSelect.addEventListener("change", (e) => {
|
||||
if (e.target.value) {
|
||||
loadFlowDetails(e.target.value);
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize
|
||||
loadFlows();
|
||||
+54
-66
@@ -79,68 +79,6 @@ async function updateClocks() {
|
||||
updateClocks();
|
||||
setInterval(updateClocks, 1000);
|
||||
|
||||
// --- Airport Autocomplete ---
|
||||
// const airportInput = document.querySelector('input[placeholder*="airport"]');
|
||||
// let dropdownDiv;
|
||||
// if (airportInput) {
|
||||
// console.log("hi");
|
||||
// dropdownDiv = document.createElement("div");
|
||||
// dropdownDiv.className =
|
||||
// "absolute bg-white border border-gray-300 rounded shadow z-10 w-full max-h-48 overflow-y-auto top-[calc(100%+10px)]";
|
||||
// dropdownDiv.style.display = "none";
|
||||
// airportInput.parentNode.appendChild(dropdownDiv);
|
||||
// airportInput.addEventListener("input", async function () {
|
||||
// const val = airportInput.value.trim();
|
||||
// if (val.length < 3) {
|
||||
// dropdownDiv.style.display = "none";
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// const res = await fetch(`/airports?search=${encodeURIComponent(val)}`);
|
||||
// if (!res.ok) throw new Error("Failed to fetch airports");
|
||||
// const airports = await res.json();
|
||||
// if (!Array.isArray(airports) || airports.length === 0) {
|
||||
// dropdownDiv.innerHTML =
|
||||
// '<div class="p-2 text-gray-500">No results</div>';
|
||||
// dropdownDiv.style.display = "block";
|
||||
// return;
|
||||
// }
|
||||
// dropdownDiv.innerHTML = airports
|
||||
// .map(
|
||||
// (a, i) =>
|
||||
// `<div class="p-2 hover:bg-sky-100 cursor-pointer" data-index="${i}">${a.name}</div>`
|
||||
// )
|
||||
// .join("");
|
||||
// dropdownDiv.style.display = "block";
|
||||
// Array.from(dropdownDiv.children).forEach((child, i) => {
|
||||
// child.addEventListener("click", () => {
|
||||
// airportInput.value = child.textContent;
|
||||
// dropdownDiv.style.display = "none";
|
||||
// selectedAirport = airports[i];
|
||||
// console.log("hey");
|
||||
// airportInput.textContent = `hold`;
|
||||
// if (selectedAirport) {
|
||||
// console.log(selectedAirport);
|
||||
// airportInput.value = `${selectedAirport.name} (${selectedAirport.code})`;
|
||||
// showMap(
|
||||
// Number(selectedAirport.latitude_deg),
|
||||
// Number(selectedAirport.longitude_deg)
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// } catch (err) {
|
||||
// dropdownDiv.innerHTML =
|
||||
// '<div class="p-2 text-red-500">Error loading airports</div>';
|
||||
// dropdownDiv.style.display = "block";
|
||||
// }
|
||||
// });
|
||||
// // Hide dropdown on blur
|
||||
// airportInput.addEventListener("blur", () =>
|
||||
// setTimeout(() => (dropdownDiv.style.display = "none"), 200)
|
||||
// );
|
||||
// }
|
||||
|
||||
// --- Airport Autocomplete ---
|
||||
const airportInput = document.querySelector('input[placeholder*="airport"]');
|
||||
let dropdownDiv;
|
||||
@@ -163,10 +101,6 @@ if (airportInput) {
|
||||
selectedAirport = currentAirports[index]; // Use latest fetched data
|
||||
airportInput.value = `${selectedAirport.name} (${selectedAirport.code})`; // Set once
|
||||
|
||||
// showMap(
|
||||
// Number(selectedAirport.latitude_deg),
|
||||
// Number(selectedAirport.longitude_deg)
|
||||
// );
|
||||
onAirportSelected(selectedAirport);
|
||||
dropdownDiv.style.display = "none";
|
||||
});
|
||||
@@ -307,6 +241,11 @@ function logWidgetClick(widgetName) {
|
||||
widget_name: widgetName,
|
||||
browser_type: navigator.userAgent,
|
||||
}),
|
||||
}).then(async (res) => {
|
||||
if (res.status === 429) {
|
||||
const data = await res.json();
|
||||
if (data.redirect) window.location.href = data.redirect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -394,6 +333,55 @@ if (coinInput && coinBtn && coinResult) {
|
||||
});
|
||||
}
|
||||
|
||||
// --- Upload Widget ---
|
||||
const uploadInput = document.querySelector(
|
||||
'input[type="file"][id="upload-input"]'
|
||||
);
|
||||
const uploadBtn = document.getElementById("upload-btn");
|
||||
const uploadPreview = document.getElementById("upload-preview");
|
||||
const uploadError = document.getElementById("upload-error");
|
||||
|
||||
async function fetchLatestUpload() {
|
||||
try {
|
||||
const res = await fetch("/upload/latest");
|
||||
const data = await res.json();
|
||||
if (data.url && uploadPreview) {
|
||||
uploadPreview.src = data.url;
|
||||
uploadPreview.style.display = "";
|
||||
} else if (uploadPreview) {
|
||||
uploadPreview.style.display = "none";
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (uploadBtn && uploadInput) {
|
||||
uploadBtn.addEventListener("click", async function () {
|
||||
if (!uploadInput.files || !uploadInput.files[0]) {
|
||||
if (uploadError) uploadError.textContent = "Please select an image.";
|
||||
return;
|
||||
}
|
||||
const formData = new FormData();
|
||||
formData.append("image", uploadInput.files[0]);
|
||||
try {
|
||||
const res = await fetch("/upload", { method: "POST", body: formData });
|
||||
const data = await res.json();
|
||||
if (data.url) {
|
||||
if (uploadPreview) {
|
||||
uploadPreview.src = data.url;
|
||||
uploadPreview.style.display = "";
|
||||
}
|
||||
if (uploadError) uploadError.textContent = "";
|
||||
} else {
|
||||
if (uploadError)
|
||||
uploadError.textContent = data.error || "Upload failed.";
|
||||
}
|
||||
} catch (err) {
|
||||
if (uploadError) uploadError.textContent = "Upload failed.";
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchLatestUpload();
|
||||
|
||||
// Attach click listeners to widgets
|
||||
function attachAnalyticListeners() {
|
||||
const widgets = [
|
||||
|
||||
+104
-73
@@ -8,14 +8,20 @@
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
||||
"Courier New", monospace;
|
||||
--color-red-500: oklch(63.7% 0.237 25.331);
|
||||
--color-green-500: oklch(72.3% 0.219 149.579);
|
||||
--color-green-600: oklch(62.7% 0.194 149.214);
|
||||
--color-sky-100: oklch(95.1% 0.026 236.824);
|
||||
--color-sky-400: oklch(74.6% 0.16 232.661);
|
||||
--color-blue-100: oklch(93.2% 0.032 255.585);
|
||||
--color-blue-500: oklch(62.3% 0.214 259.815);
|
||||
--color-blue-600: oklch(54.6% 0.245 262.881);
|
||||
--color-blue-700: oklch(48.8% 0.243 264.376);
|
||||
--color-gray-100: oklch(96.7% 0.003 264.542);
|
||||
--color-gray-300: oklch(87.2% 0.01 258.338);
|
||||
--color-gray-500: oklch(55.1% 0.027 264.364);
|
||||
--color-gray-600: oklch(44.6% 0.03 256.802);
|
||||
--color-white: #fff;
|
||||
--spacing: 0.25rem;
|
||||
--container-2xl: 42rem;
|
||||
--text-xs: 0.75rem;
|
||||
--text-xs--line-height: calc(1 / 0.75);
|
||||
--text-sm: 0.875rem;
|
||||
@@ -198,6 +204,27 @@
|
||||
.row-span-2 {
|
||||
grid-row: span 2 / span 2;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
@media (width >= 40rem) {
|
||||
max-width: 40rem;
|
||||
}
|
||||
@media (width >= 48rem) {
|
||||
max-width: 48rem;
|
||||
}
|
||||
@media (width >= 64rem) {
|
||||
max-width: 64rem;
|
||||
}
|
||||
@media (width >= 80rem) {
|
||||
max-width: 80rem;
|
||||
}
|
||||
@media (width >= 96rem) {
|
||||
max-width: 96rem;
|
||||
}
|
||||
}
|
||||
.mx-auto {
|
||||
margin-inline: auto;
|
||||
}
|
||||
.mt-2 {
|
||||
margin-top: calc(var(--spacing) * 2);
|
||||
}
|
||||
@@ -210,6 +237,12 @@
|
||||
.mb-2 {
|
||||
margin-bottom: calc(var(--spacing) * 2);
|
||||
}
|
||||
.mb-4 {
|
||||
margin-bottom: calc(var(--spacing) * 4);
|
||||
}
|
||||
.mb-6 {
|
||||
margin-bottom: calc(var(--spacing) * 6);
|
||||
}
|
||||
.ml-2 {
|
||||
margin-left: calc(var(--spacing) * 2);
|
||||
}
|
||||
@@ -228,6 +261,9 @@
|
||||
.h-24 {
|
||||
height: calc(var(--spacing) * 24);
|
||||
}
|
||||
.h-96 {
|
||||
height: calc(var(--spacing) * 96);
|
||||
}
|
||||
.h-244 {
|
||||
height: calc(var(--spacing) * 244);
|
||||
}
|
||||
@@ -252,6 +288,12 @@
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
.max-w-2xl {
|
||||
max-width: var(--container-2xl);
|
||||
}
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -276,6 +318,9 @@
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.gap-2 {
|
||||
gap: calc(var(--spacing) * 2);
|
||||
}
|
||||
.gap-8 {
|
||||
gap: calc(var(--spacing) * 8);
|
||||
}
|
||||
@@ -302,12 +347,15 @@
|
||||
.border-gray-300 {
|
||||
border-color: var(--color-gray-300);
|
||||
}
|
||||
.bg-blue-100 {
|
||||
background-color: var(--color-blue-100);
|
||||
.bg-blue-500 {
|
||||
background-color: var(--color-blue-500);
|
||||
}
|
||||
.bg-gray-100 {
|
||||
background-color: var(--color-gray-100);
|
||||
}
|
||||
.bg-green-500 {
|
||||
background-color: var(--color-green-500);
|
||||
}
|
||||
.bg-inherit {
|
||||
background-color: inherit;
|
||||
}
|
||||
@@ -317,6 +365,9 @@
|
||||
.bg-white {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
.object-cover {
|
||||
object-fit: cover;
|
||||
}
|
||||
.p-2 {
|
||||
padding: calc(var(--spacing) * 2);
|
||||
}
|
||||
@@ -329,6 +380,12 @@
|
||||
.p-8 {
|
||||
padding: calc(var(--spacing) * 8);
|
||||
}
|
||||
.px-3 {
|
||||
padding-inline: calc(var(--spacing) * 3);
|
||||
}
|
||||
.px-6 {
|
||||
padding-inline: calc(var(--spacing) * 6);
|
||||
}
|
||||
.px-8 {
|
||||
padding-inline: calc(var(--spacing) * 8);
|
||||
}
|
||||
@@ -373,9 +430,15 @@
|
||||
--tw-font-weight: var(--font-weight-semibold);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.text-blue-700 {
|
||||
color: var(--color-blue-700);
|
||||
}
|
||||
.text-gray-500 {
|
||||
color: var(--color-gray-500);
|
||||
}
|
||||
.text-gray-600 {
|
||||
color: var(--color-gray-600);
|
||||
}
|
||||
.text-red-500 {
|
||||
color: var(--color-red-500);
|
||||
}
|
||||
@@ -390,14 +453,24 @@
|
||||
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
.blur {
|
||||
--tw-blur: blur(8px);
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||
}
|
||||
.outline-none {
|
||||
--tw-outline-style: none;
|
||||
outline-style: none;
|
||||
}
|
||||
.hover\:bg-blue-600 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
background-color: var(--color-blue-600);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-green-600 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
background-color: var(--color-green-600);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-sky-100 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
@@ -405,6 +478,30 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:underline {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
.focus\:ring-2 {
|
||||
&:focus {
|
||||
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
||||
}
|
||||
}
|
||||
.focus\:ring-blue-500 {
|
||||
&:focus {
|
||||
--tw-ring-color: var(--color-blue-500);
|
||||
}
|
||||
}
|
||||
.focus\:outline-none {
|
||||
&:focus {
|
||||
--tw-outline-style: none;
|
||||
outline-style: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@property --tw-space-y-reverse {
|
||||
syntax: "*";
|
||||
@@ -485,59 +582,6 @@
|
||||
inherits: false;
|
||||
initial-value: 0 0 #0000;
|
||||
}
|
||||
@property --tw-blur {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-brightness {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-contrast {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-grayscale {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-hue-rotate {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-invert {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-opacity {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-saturate {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-sepia {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-drop-shadow {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-drop-shadow-color {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@property --tw-drop-shadow-alpha {
|
||||
syntax: "<percentage>";
|
||||
inherits: false;
|
||||
initial-value: 100%;
|
||||
}
|
||||
@property --tw-drop-shadow-size {
|
||||
syntax: "*";
|
||||
inherits: false;
|
||||
}
|
||||
@layer properties {
|
||||
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
||||
*, ::before, ::after, ::backdrop {
|
||||
@@ -558,19 +602,6 @@
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-blur: initial;
|
||||
--tw-brightness: initial;
|
||||
--tw-contrast: initial;
|
||||
--tw-grayscale: initial;
|
||||
--tw-hue-rotate: initial;
|
||||
--tw-invert: initial;
|
||||
--tw-opacity: initial;
|
||||
--tw-saturate: initial;
|
||||
--tw-sepia: initial;
|
||||
--tw-drop-shadow: initial;
|
||||
--tw-drop-shadow-color: initial;
|
||||
--tw-drop-shadow-alpha: 100%;
|
||||
--tw-drop-shadow-size: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user