Mobile Home Page Update

This commit is contained in:
2026-01-25 15:42:20 +00:00
parent 34eba52461
commit 372b797f3e

View File

@@ -8,38 +8,62 @@
name: "Plastic Water Bottle",
date: "Today, 10:45 AM",
severity: "High",
icon: "ri:drop-fill",
image: "/water-bottle.png",
impact: "Negative Impact",
},
{
id: 2,
name: "Organic Banana",
date: "Yesterday, 3:20 PM",
severity: "Low",
icon: "ri:plant-fill",
image: "/banana.png",
impact: "Positive Choice",
},
{
id: 3,
name: "Aluminum Soda Can",
date: "Mon, 12:15 PM",
severity: "Low",
icon: "ri:cup-fill",
image: "/soda-can.png",
impact: "Recyclable",
},
{
id: 4,
name: "Takeout Container",
date: "Sun, 8:30 PM",
severity: "Medium",
icon: "ri:box-3-fill",
image: "/container.png",
impact: "Mixed Materials",
},
{
id: 5,
name: "Shampoo Bottle",
date: "Sat, 11:00 AM",
severity: "High",
icon: "ri:flask-fill",
image: "/shampoo.png",
impact: "High Plastic",
},
];
interface ScanItem {
id: number;
name: string;
date: string;
severity: string;
image: string;
impact: string;
}
let selectedScan = $state<ScanItem | null>(null);
function openScan(scan: ScanItem) {
selectedScan = scan;
}
function closeScan() {
selectedScan = null;
}
let greeting = $state("Hello");
onMount(() => {
@@ -52,122 +76,90 @@
function getSeverityClass(severity: string): string {
return severity.toLowerCase();
}
function getSeverityColor(severity: string): string {
switch (severity.toLowerCase()) {
case "low":
return "#34d399";
case "medium":
return "#fb923c";
case "high":
return "#f87171";
default:
return "#9ca3af";
}
}
</script>
<div class="mobile-home">
<header class="header">
<div class="header-left">
<div class="avatar">
<img
src="/ethix-logo.png"
alt="Ethix Logo"
class="avatar-logo"
/>
</div>
<div class="header-text">
<span class="greeting">{greeting}</span>
<h1 class="username">Eco Warrior</h1>
</div>
</div>
<button class="notification-btn" aria-label="Notifications">
<Icon
icon="ri:notification-3-line"
width="24"
style="color: #9ca3af;"
/>
<span class="notif-badge">2</span>
</button>
</header>
<div class="min-h-screen bg-[#051f18] text-white px-5 pt-4 pb-32">
<section class="impact-hero">
<div class="impact-main">
<span class="impact-label">Your Carbon Savings</span>
<div class="impact-value">
<span class="impact-number">23</span>
<span class="impact-unit">kg CO₂</span>
</div>
<div class="impact-comparison">
<Icon icon="ri:car-fill" width="16" style="color: #6ee7b7;" />
<span>≈ driving 92 km less</span>
</div>
</div>
<div class="impact-visual">
<div class="tree-ring">
<Icon icon="ri:tree-fill" width="32" style="color: #10b981;" />
</div>
<span class="tree-count">2 trees planted</span>
</div>
</section>
<section class="stats-row">
<div class="stat-pill">
<div class="stat-icon">
<section class="flex gap-3 mb-7">
<div
class="flex-1 flex flex-col items-center gap-2 py-4 px-2 bg-[#0d2e25] border border-[#1f473b] rounded-2xl"
>
<div
class="w-9 h-9 bg-emerald-500/10 rounded-xl flex items-center justify-center"
>
<Icon
icon="ri:qr-scan-2-line"
width="20"
style="color: #34d399;"
class="text-emerald-400"
/>
</div>
<span class="stat-value">47</span>
<span class="stat-label">scans</span>
<span class="text-lg font-extrabold text-white">47</span>
<span
class="text-[10px] text-gray-400 uppercase tracking-wide font-semibold"
>scans</span
>
</div>
<div class="stat-pill">
<div class="stat-icon eco">
<div
class="flex-1 flex flex-col items-center gap-2 py-4 px-2 bg-[#0d2e25] border border-[#1f473b] rounded-2xl"
>
<div
class="w-9 h-9 bg-emerald-500/10 rounded-xl flex items-center justify-center"
>
<Icon
icon="ri:checkbox-circle-fill"
width="20"
style="color: #34d399;"
class="text-emerald-400"
/>
</div>
<span class="stat-value">32</span>
<span class="stat-label">eco picks</span>
</div>
<div class="stat-pill">
<div class="stat-icon score">
<Icon icon="ri:star-fill" width="20" style="color: #fbbf24;" />
</div>
<span class="stat-value">78%</span>
<span class="stat-label">score</span>
<span class="text-lg font-extrabold text-white">32</span>
<span
class="text-[10px] text-gray-400 uppercase tracking-wide font-semibold"
>eco picks</span
>
</div>
</section>
<section class="recent-section">
<div class="section-header">
<h2>Recent Scans</h2>
<a href="/history" class="see-all">
See all
<Icon icon="ri:arrow-right-s-line" width="16" />
</a>
</div>
<div class="scan-list">
<div class="flex flex-col gap-2.5">
{#each scanHistory as item (item.id)}
<button class="scan-item" aria-label="View {item.name}">
<div
class="item-icon"
style="color: {getSeverityColor(item.severity)};"
>
<Icon icon={item.icon} width="24" />
<button
class="flex items-center gap-3.5 p-3 bg-[#0d2e25] border border-[#1f473b] rounded-2xl cursor-pointer w-full text-left transition-transform active:scale-98 active:bg-[#1f473b]"
onclick={() => openScan(item)}
aria-label="View {item.name}"
>
<div class="w-12 h-12 rounded-xl overflow-hidden shrink-0">
{#if item.image}
<img
src={item.image}
alt={item.name}
class="w-full h-full object-cover"
/>
{:else}
<div
class="w-full h-full flex items-center justify-center font-bold text-[#051f18]"
style="background-color: {getSeverityClass(
item.severity,
) === 'high'
? '#fca5a5'
: '#86efac'}"
>
<span class="text-lg">{item.name[0]}</span>
</div>
{/if}
</div>
<div class="item-info">
<span class="item-name">{item.name}</span>
<span class="item-date">{item.date}</span>
<div class="flex-1 flex flex-col gap-0.5 min-w-0">
<span class="text-sm font-semibold text-white truncate"
>{item.name}</span
>
<span class="text-xs text-gray-400">{item.date}</span>
</div>
<span
class="severity-tag {getSeverityClass(item.severity)}"
class="px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wide {item.severity.toLowerCase() ===
'high'
? 'bg-red-400/10 text-red-400 border border-red-400/20'
: item.severity.toLowerCase() === 'medium'
? 'bg-orange-400/10 text-orange-400 border border-orange-400/20'
: 'bg-emerald-400/10 text-emerald-400 border border-emerald-400/20'}"
>
{item.severity}
</span>
@@ -176,365 +168,78 @@
</div>
</section>
<section class="tip-card">
<div class="tip-icon">
<Icon
icon="ri:lightbulb-flash-fill"
width="22"
style="color: #fbbf24;"
/>
{#if selectedScan}
<div
class="fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-5"
role="button"
tabindex="0"
onkeydown={(e) => e.key === "Escape" && closeScan()}
onclick={closeScan}
>
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="bg-[#0d2e25] border border-[#1f473b] rounded-3xl w-full max-w-[340px] p-6 relative shadow-[0_20px_50px_rgba(0,0,0,0.5)]"
role="document"
tabindex="-1"
onkeydown={(e) => e.key === "Escape" && closeScan()}
onclick={(e) => e.stopPropagation()}
>
<button
class="absolute top-4 right-4 bg-transparent border-none text-gray-400 cursor-pointer"
onclick={closeScan}
>
<Icon icon="ri:close-fill" width="24" />
</button>
<div class="text-center mb-5">
<span
class="text-xs text-gray-400 uppercase tracking-widest"
>{selectedScan.date}</span
>
<h2 class="text-xl text-white m-0 mt-1">Scan Report</h2>
</div>
<div
class="w-full h-[200px] bg-black rounded-2xl mb-5 overflow-hidden"
>
{#if selectedScan.image}
<img
src={selectedScan.image}
alt={selectedScan.name}
class="w-full h-full object-cover"
/>
{:else}
<div
class="w-full h-full flex items-center justify-center"
style="background-color: {getSeverityClass(
selectedScan.severity,
) === 'high'
? '#fca5a5'
: '#86efac'}"
>
<span class="text-6xl text-[#051f18] font-black"
>{selectedScan.name[0]}</span
>
</div>
{/if}
</div>
<div class="text-center">
<h3 class="text-lg text-white m-0 mb-1">
{selectedScan.name}
</h3>
<p class="text-gray-300 text-sm mb-3">
{selectedScan.impact}
</p>
<div
class="inline-block px-3 py-1.5 rounded-full text-xs font-bold uppercase {selectedScan.severity.toLowerCase() ===
'high'
? 'bg-red-400/20 text-red-400'
: selectedScan.severity.toLowerCase() === 'medium'
? 'bg-orange-400/20 text-orange-400'
: 'bg-emerald-400/20 text-emerald-400'}"
>
Severity: {selectedScan.severity}
</div>
</div>
</div>
</div>
<div class="tip-text">
<strong>Daily Tip:</strong> Bring reusable bags shopping to cut 500 plastic
bags per year!
</div>
</section>
{/if}
</div>
<style>
.mobile-home {
padding: 16px 20px 120px;
min-height: 100vh;
background: #051f18;
color: white;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
padding-top: 8px;
}
.header-left {
display: flex;
align-items: center;
gap: 12px;
}
.avatar {
width: 48px;
height: 48px;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.avatar-logo {
width: 36px;
height: 36px;
object-fit: contain;
}
.header-text {
display: flex;
flex-direction: column;
}
.greeting {
font-size: 13px;
color: #9ca3af;
}
.username {
font-size: 20px;
font-weight: 800;
color: white;
margin: 0;
}
.notification-btn {
position: relative;
width: 44px;
height: 44px;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.notif-badge {
position: absolute;
top: -2px;
right: -2px;
width: 18px;
height: 18px;
background: #ef4444;
color: white;
font-size: 10px;
font-weight: 700;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #051f18;
}
.impact-hero {
display: flex;
justify-content: space-between;
align-items: center;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 20px;
padding: 24px;
margin-bottom: 24px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.impact-main {
display: flex;
flex-direction: column;
gap: 4px;
}
.impact-label {
font-size: 11px;
color: #6ee7b7;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: 700;
}
.impact-value {
display: flex;
align-items: baseline;
gap: 6px;
}
.impact-number {
font-size: 36px;
font-weight: 900;
color: white;
line-height: 1;
}
.impact-unit {
font-size: 16px;
color: #9ca3af;
font-weight: 600;
}
.impact-comparison {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: #d1fae5;
margin-top: 8px;
}
.impact-visual {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.tree-ring {
width: 64px;
height: 64px;
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.tree-count {
font-size: 11px;
color: #34d399;
font-weight: 700;
}
.stats-row {
display: flex;
gap: 12px;
margin-bottom: 28px;
}
.stat-pill {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 16px 8px;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 16px;
}
.stat-icon {
width: 36px;
height: 36px;
background: rgba(16, 185, 129, 0.1);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.stat-value {
font-size: 18px;
font-weight: 800;
color: white;
}
.stat-label {
font-size: 10px;
color: #9ca3af;
text-transform: uppercase;
letter-spacing: 0.5px;
font-weight: 600;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.section-header h2 {
font-size: 16px;
font-weight: 800;
color: white;
margin: 0;
}
.see-all {
display: flex;
align-items: center;
gap: 2px;
font-size: 13px;
color: #34d399;
text-decoration: none;
font-weight: 600;
}
.scan-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.scan-item {
display: flex;
align-items: center;
gap: 14px;
padding: 12px;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 16px;
cursor: pointer;
width: 100%;
text-align: left;
transition: transform 0.1s;
}
.scan-item:active {
transform: scale(0.98);
background: #1f473b;
}
.item-icon {
width: 44px;
height: 44px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
background: #051f18;
}
.item-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.item-name {
font-size: 14px;
font-weight: 600;
color: white;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-date {
font-size: 12px;
color: #9ca3af;
}
.severity-tag {
padding: 4px 10px;
border-radius: 20px;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.severity-tag.low {
background: rgba(52, 211, 153, 0.1);
color: #34d399;
border: 1px solid rgba(52, 211, 153, 0.2);
}
.severity-tag.medium {
background: rgba(251, 146, 60, 0.1);
color: #fb923c;
border: 1px solid rgba(251, 146, 60, 0.2);
}
.severity-tag.high {
background: rgba(248, 113, 113, 0.1);
color: #f87171;
border: 1px solid rgba(248, 113, 113, 0.2);
}
.tip-card {
display: flex;
gap: 14px;
padding: 20px;
background: #0d2e25;
border: 1px solid #1f473b;
border-radius: 16px;
margin-top: 24px;
}
.tip-icon {
width: 40px;
height: 40px;
background: rgba(251, 191, 36, 0.1);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.tip-text {
font-size: 13px;
color: #d1d5db;
line-height: 1.5;
}
.tip-text strong {
color: white;
font-weight: 700;
}
</style>