← back to Model Arena
data/artifacts/0b2f260ffe00/qwen3-14b.html
382 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fish CRM</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #f4f9ff;
color: #333;
display: flex;
flex-direction: column;
min-height: 100vh;
padding: 20px;
scroll-behavior: smooth;
overflow-x: hidden;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
header h1 {
font-size: 1.5rem;
margin-right: 10px;
}
.search-bar {
position: relative;
width: 300px;
max-width: 100%;
}
.search-bar input {
padding: 8px 12px;
width: 100%;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
.search-bar button {
position: absolute;
right: 5px;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
font-size: 1.2rem;
color: #666;
cursor: pointer;
}
.quick-add {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 20px;
}
.quick-add input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
flex: 1;
min-width: 150px;
}
.quick-add button {
padding: 8px 12px;
font-size: 1rem;
border: none;
border-radius: 4px;
background-color: #4caf50;
color: white;
cursor: pointer;
}
.quick-add button:hover {
background-color: #45a049;
}
.stages {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 20px;
}
.stage {
background: #e0f7fa;
padding: 10px 20px;
border-radius: 8px;
text-align: center;
flex: 1;
min-width: 120px;
}
.stage h3 {
margin: 5px 0 0;
font-size: 0.9rem;
}
.tally {
font-size: 1.4rem;
font-weight: bold;
margin-top: 5px;
}
.main {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.line {
position: relative;
width: 100%;
min-height: 150px;
background: #e3f2fd;
border: 2px dashed #90caf9;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 10px;
}
.line.dragging {
background: #d1f7ee;
border-color: #4caf50;
}
.line.drag-over {
border-color: #2196f3;
}
.line.drag-target {
border-color: #4caf50;
background: #e8f5e9;
}
.fish {
position: absolute;
padding: 10px 20px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
border: 1px solid #ddd;
transition: all 0.3s ease;
user-select: none;
}
.fish.dragging {
opacity: 0.8;
z-index: 10;
transform: translateY(-10px);
}
.fish:active {
transform: scale(1.05);
}
.fish.drag-over {
background: #e0f7fa;
}
.fish.drag-target {
border-color: #4caf50;
background: #e8f5e9;
}
.fish.drag-over:after {
content: 'Drop here';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
font-size: 0.9rem;
background: white;
padding: 4px 8px;
border-radius: 4px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.fish .info {
font-size: 0.9rem;
color: #666;
margin-top: 5px;
}
.info-box {
margin-top: 10px;
font-size: 0.9rem;
color: #555;
}
.info-box.error {
color: #d32f2f;
}
.info-box.success {
color: #2e7d32;
}
footer {
margin-top: auto;
font-size: 0.9rem;
color: #888;
text-align: center;
padding: 10px;
}
@media (min-width: 768px) {
.main {
flex-wrap: nowrap;
}
.line {
width: calc(33.333% - 10px);
}
}
@media (min-width: 1024px) {
.main {
flex-wrap: nowrap;
}
.line {
width: calc(25% - 10px);
}
}
@media (min-width: 1200px) {
.line {
width: calc(16.666% - 10px);
}
}
</style>
</head>
<body>
<header>
<h1>Fish CRM</h1>
<div class="search-bar">
<input type="text" id="search" placeholder="Search fish..." oninput="searchFish()" />
<button onclick="searchFish()">🔍</button>
</div>
</header>
<div class="quick-add">
<input type="text" id="quickName" placeholder="Fish name" />
<input type="text" id="quickSpecies" placeholder="Species" />
<button onclick="addFish()">➕ Add Fish</button>
</div>
<div class="stages">
<div class="stage">
<h3>Nibble</h3>
<div class="tally" id="tally-nibble">0</div>
</div>
<div class="stage">
<h3>Hooked</h3>
<div class="tally" id="tally-hooked">0</div>
</div>
<div class="stage">
<h3>Landed</h3>
<div class="tally" id="tally-landed">0</div>
</div>
</div>
<div class="main">
<div class="line" id="line-nibble" data-stage="nibble" ondragover="handleDragOver(event)" ondrop="handleDrop(event)">
<div class="fish" draggable="true" ondragstart="dragFish(event)" id="fish-nibble-1">
<div>Betty</div>
<div class="info">Bass | 12 cm</div>
</div>
<div class="fish" draggable="true" ondragstart="dragFish(event)" id="fish-nibble-2">
<div>Wally</div>
<div class="info">Perch | 15 cm</div>
</div>
<div class="info-box">Drag fish to move stages</div>
</div>
<div class="line" id="line-hooked" data-stage="hooked" ondragover="handleDragOver(event)" ondrop="handleDrop(event)">
<div class="fish" draggable="true" ondragstart="dragFish(event)" id="fish-hooked-1">
<div>Sal</div>
<div class="info">Salmon | 20 cm</div>
</div>
<div class="info-box">No fish here</div>
</div>
<div class="line" id="line-landed" data-stage="landed" ondragover="handleDragOver(event)" ondrop="handleDrop(event)">
<div class="info-box">No fish here</div>
</div>
<div class="line" id="line-nibble-2" data-stage="nibble" ondragover="handleDragOver(event)" ondrop="handleDrop(event)">
<div class="fish" draggable="true" ondragstart="dragFish(event)" id="fish-nibble-3">
<div>Derek</div>
<div class="info">Trout | 18 cm</div>
</div>
</div>
</div>
<footer>
Fish CRM - Manage your aquatic leads with style
</footer>
<script>
const lines = document.querySelectorAll('.line');
const fishEls = document.querySelectorAll('.fish');
const stageTallies = {
nibble: document.getElementById('tally-nibble'),
hooked: document.getElementById('tally-hooked'),
landed: document.getElementById('tally-landed')
};
let draggedFish = null;
let draggedStage = null;
function addFish() {
const name = document.getElementById('quickName').value.trim();
const species = document.getElementById('quickSpecies').value.trim();
if (!name || !species) {
showStatus('error', 'Both name and species are required.');
return;
}
const newFish = document.createElement('div');
newFish.className = 'fish';
newFish.draggable = true;
newFish.id = `fish-nibble-${Date.now()}`;
newFish.setAttribute('draggable', true);
newFish.innerHTML = `
<div>${name}</div>
<div class="info">${species} | ${Math.floor(Math.random() * 20 + 10)} cm</div>
`;
newFish.addEventListener('dragstart', (e) => dragFish(e));
document.getElementById('line-nibble').appendChild(newFish);
document.getElementById('quickName').value = '';
document.getElementById('quickSpecies').value = '';
showStatus('success', 'Fish added successfully!');
}
function dragFish(e) {
draggedFish = e.target;
draggedStage = e.target.closest('.line').dataset.stage;
}
function handleDragOver(e) {
if (e.target.classList.contains('line')) {
e.preventDefault();
e.target.classList.add('drag-over');
}
}
function handleDrop(e) {
e.preventDefault();
if (!draggedFish) return;
const targetLine = e.target.closest('.line');
if (targetLine && draggedFish.parentNode && draggedFish.parentNode !== targetLine) {
const oldStage = draggedStage;
const newStage = targetLine.dataset.stage;
targetLine.appendChild(draggedFish);
draggedFish.classList.remove('dragging');
targetLine.classList.remove('drag-over');
targetLine.classList.remove('drag-target');
updateTally(oldStage, -1);
updateTally(newStage, 1);
}
draggedFish = null;
draggedStage = null;
}
function updateTally(stage, delta) {
let count = parseInt(stageTallies[stage].textContent) || 0;
count += delta;
stageTallies[stage].textContent = count;
}
function searchFish() {
const query = document.getElementById('search').value.toLowerCase();
fishEls.forEach(fish => {
const name = fish.textContent.trim().toLowerCase();
fish.style.display = query ? (name.includes(query) ? 'block' : 'none') : 'block';
});
}
function showStatus(type, message) {
const status = document.createElement('div');
status.className = `info-box ${type}`;
status.textContent = message;
document.body.appendChild(status);
setTimeout(() => {
status.remove();
}, 3000);
}
// Initialize tallies based on current fish
document.querySelectorAll('.line').forEach(line => {
const count = line.querySelectorAll('.fish').length;
const stage = line.dataset.stage;
updateTally(stage, count);
});
</script>
</body>
</html>