fix: Fix syntax errors introduced by shell interpolation in dashboard and edit pages
This commit is contained in:
@@ -26,7 +26,7 @@ export default function EditQRPage() {
|
||||
width: 300,
|
||||
height: 300,
|
||||
type: 'svg',
|
||||
data: $baseUrl/l/preview,
|
||||
data: `${baseUrl}/l/preview`,
|
||||
margin: 10,
|
||||
qrOptions: { typeNumber: 0, mode: 'Byte', errorCorrectionLevel: 'Q' },
|
||||
imageOptions: { hideBackgroundDots: true, imageSize: 0.4, margin: 5 },
|
||||
@@ -44,7 +44,7 @@ export default function EditQRPage() {
|
||||
}).catch(() => {});
|
||||
|
||||
// Fetch existing QR Data
|
||||
api.get(/qr/ + qrId).then(res => {
|
||||
api.get(`/qr/${qrId}`).then(res => {
|
||||
const qr = res.data.qr_code;
|
||||
setQrName(qr.name);
|
||||
setDestinationUrl(qr.destination_url);
|
||||
@@ -54,7 +54,7 @@ export default function EditQRPage() {
|
||||
if (qr.design_data) {
|
||||
setQrOptions({
|
||||
...qr.design_data,
|
||||
data: qr.type === 'static' ? qr.destination_url : $baseUrl/l/ + qr.short_url_id
|
||||
data: qr.type === 'static' ? qr.destination_url : `${baseUrl}/l/${qr.short_url_id}`
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
@@ -70,13 +70,13 @@ export default function EditQRPage() {
|
||||
if (qrType === 'static') return;
|
||||
const val = e.target.value.replace(/[^a-zA-Z0-9-_]/g, '');
|
||||
setCustomSlug(val);
|
||||
setQrOptions(prev => ({ ...prev, data: $baseUrl/l/ + val }));
|
||||
setQrOptions(prev => ({ ...prev, data: `${baseUrl}/l/${val}` }));
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
setIsSaving(true);
|
||||
await api.put(/qr/ + qrId, {
|
||||
await api.put(`/qr/${qrId}`, {
|
||||
name: qrName,
|
||||
destinationUrl: destinationUrl,
|
||||
shortUrlId: qrType === 'dynamic' ? customSlug : undefined,
|
||||
@@ -129,7 +129,7 @@ export default function EditQRPage() {
|
||||
<button
|
||||
onClick={() => handleDownload('svg')}
|
||||
disabled={userRole === 'free' || userRole === 'free_trial'}
|
||||
className={px-6 py-2.5 rounded-lg font-semibold shadow-sm transition-colors border border-gray-300 }
|
||||
className={`px-6 py-2.5 rounded-lg font-semibold shadow-sm transition-colors border border-gray-300 ${userRole === 'free' || userRole === 'free_trial' ? 'bg-gray-100 text-gray-400 cursor-not-allowed' : 'bg-white text-gray-700 hover:bg-gray-50'}`}
|
||||
title={userRole === 'free' || userRole === 'free_trial' ? 'SVG export is for Pro users' : 'Download SVG'}
|
||||
>
|
||||
{userRole === 'free' || userRole === 'free_trial' ? 'Download SVG (Pro)' : 'Download SVG'}
|
||||
@@ -185,7 +185,7 @@ export default function EditQRPage() {
|
||||
}
|
||||
}}
|
||||
disabled={qrType === 'static'}
|
||||
className={w-full rounded-lg shadow-sm p-3 border focus:ring-indigo-500 focus:border-indigo-500 text-gray-900 }
|
||||
className={`w-full rounded-lg shadow-sm p-3 border focus:ring-indigo-500 focus:border-indigo-500 text-gray-900 ${qrType === 'static' ? 'bg-gray-100 border-gray-200 text-gray-500' : 'bg-white border-gray-300'}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use client';
|
||||
'use client';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/navigation';
|
||||
@@ -50,7 +50,7 @@ export default function DashboardPage() {
|
||||
setLoading(true);
|
||||
let url = '/qr';
|
||||
if (selectedFolder !== 'all') {
|
||||
url += ?folderId= + selectedFolder;
|
||||
url += `?folderId=${selectedFolder}`;
|
||||
}
|
||||
|
||||
const [res, authRes] = await Promise.all([
|
||||
@@ -93,7 +93,7 @@ export default function DashboardPage() {
|
||||
const handleDeleteFolder = async (id: string) => {
|
||||
if (!confirm('Are you sure? QRs in this folder will be moved to the default folder.')) return;
|
||||
try {
|
||||
await api.delete(/folders/ + id);
|
||||
await api.delete(`/folders/${id}`);
|
||||
setFolders(folders.filter(f => f.id !== id));
|
||||
if (selectedFolder === id) setSelectedFolder('all');
|
||||
fetchQRs(); // refresh QRs just in case
|
||||
@@ -105,7 +105,7 @@ export default function DashboardPage() {
|
||||
const handleMoveQr = async (folderId: string | 'default') => {
|
||||
if (!moveQrId) return;
|
||||
try {
|
||||
await api.put(/qr/ + moveQrId, { folderId });
|
||||
await api.put(`/qr/${moveQrId}`, { folderId });
|
||||
setMoveQrId(null);
|
||||
fetchQRs();
|
||||
} catch (err) {
|
||||
@@ -116,7 +116,7 @@ export default function DashboardPage() {
|
||||
const handleDelete = async (id: string) => {
|
||||
if (!confirm('Are you sure you want to delete this QR code? The link will immediately stop working.')) return;
|
||||
try {
|
||||
await api.delete(/qr/ + id);
|
||||
await api.delete(`/qr/${id}`);
|
||||
setQrs(qrs.filter(qr => qr.id !== id));
|
||||
} catch (err) {
|
||||
alert('Failed to delete QR code');
|
||||
@@ -127,7 +127,7 @@ export default function DashboardPage() {
|
||||
try {
|
||||
const QRCodeStyling = (await import('qr-code-styling')).default;
|
||||
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://qr.houseofwebsites.ai';
|
||||
const shortUrl = baseUrl + '/l/' + qr.short_url_id;
|
||||
const shortUrl = `${baseUrl}/l/${qr.short_url_id}`;
|
||||
|
||||
const qrCode = new QRCodeStyling({
|
||||
...qr.design_data,
|
||||
@@ -152,13 +152,13 @@ export default function DashboardPage() {
|
||||
<div className="space-y-1 mb-6">
|
||||
<button
|
||||
onClick={() => setSelectedFolder('all')}
|
||||
className={w-full text-left px-3 py-2 rounded-lg transition-colors text-sm font-medium }
|
||||
className={`w-full text-left px-3 py-2 rounded-lg transition-colors text-sm font-medium ${selectedFolder === 'all' ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100'}`}
|
||||
>
|
||||
All QR Codes
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedFolder('default')}
|
||||
className={w-full text-left px-3 py-2 rounded-lg transition-colors text-sm font-medium }
|
||||
className={`w-full text-left px-3 py-2 rounded-lg transition-colors text-sm font-medium ${selectedFolder === 'default' ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100'}`}
|
||||
>
|
||||
Default Folder
|
||||
</button>
|
||||
@@ -167,11 +167,11 @@ export default function DashboardPage() {
|
||||
<div key={folder.id} className="flex group">
|
||||
<button
|
||||
onClick={() => setSelectedFolder(folder.id)}
|
||||
className={lex-1 text-left px-3 py-2 rounded-l-lg transition-colors text-sm font-medium truncate }
|
||||
className={`flex-1 text-left px-3 py-2 rounded-l-lg transition-colors text-sm font-medium truncate ${selectedFolder === folder.id ? 'bg-indigo-50 text-indigo-700' : 'text-gray-700 hover:bg-gray-100 group-hover:bg-gray-100'}`}
|
||||
>
|
||||
{folder.name}
|
||||
</button>
|
||||
<button onClick={() => handleDeleteFolder(folder.id)} className={px-2 rounded-r-lg text-gray-400 hover:text-red-600 transition-colors }>
|
||||
<button onClick={() => handleDeleteFolder(folder.id)} className={`px-2 rounded-r-lg text-gray-400 hover:text-red-600 transition-colors ${selectedFolder === folder.id ? 'bg-indigo-50' : 'hover:bg-gray-100 group-hover:bg-gray-100'}`}>
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -225,20 +225,20 @@ export default function DashboardPage() {
|
||||
|
||||
{/* QR Image Custom Thumbnail */}
|
||||
<div className="w-32 h-32 flex-shrink-0 flex items-center justify-center relative border border-gray-100 rounded-xl overflow-hidden bg-gray-50">
|
||||
<LiveThumbnail options={{ ...qr.design_data, data: baseUrl + '/l/' + qr.short_url_id }} />
|
||||
<LiveThumbnail options={{ ...qr.design_data, data: `${baseUrl}/l/${qr.short_url_id}` }} />
|
||||
</div>
|
||||
|
||||
{/* Info Area */}
|
||||
<div className="flex-1 min-w-0 w-full">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h3 className="text-xl font-bold text-gray-900 truncate">{qr.name}</h3>
|
||||
<Link href={/dashboard/edit/ + qr.id} className="text-gray-400 hover:text-indigo-600 transition-colors" title="Edit QR settings">
|
||||
<Link href={`/dashboard/edit/${qr.id}`} className="text-gray-400 hover:text-indigo-600 transition-colors" title="Edit QR settings">
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" /></svg>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<a href={${baseUrl}/l/} target="_blank" rel="noopener noreferrer" className="text-indigo-600 font-bold hover:underline flex items-center gap-1 text-sm bg-indigo-50 inline-flex px-3 py-1.5 rounded-lg border border-indigo-100 truncate max-w-full">
|
||||
<a href={`${baseUrl}/l/${qr.short_url_id}`} target="_blank" rel="noopener noreferrer" className="text-indigo-600 font-bold hover:underline flex items-center gap-1 text-sm bg-indigo-50 inline-flex px-3 py-1.5 rounded-lg border border-indigo-100 truncate max-w-full">
|
||||
{baseUrl}/l/{qr.short_url_id}
|
||||
<svg className="w-3 h-3 ml-1 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" /></svg>
|
||||
</a>
|
||||
@@ -273,7 +273,11 @@ export default function DashboardPage() {
|
||||
<button
|
||||
onClick={() => handleDownload(qr, 'svg')}
|
||||
disabled={userRole === 'free' || userRole === 'free_trial'}
|
||||
className={lex-1 font-bold py-2 px-2 rounded-lg transition-colors flex justify-center items-center text-sm shadow-sm }
|
||||
className={`flex-1 font-bold py-2 px-2 rounded-lg transition-colors flex justify-center items-center text-sm shadow-sm ${
|
||||
userRole === 'free' || userRole === 'free_trial'
|
||||
? 'bg-gray-200 text-gray-500 cursor-not-allowed'
|
||||
: 'bg-green-500 hover:bg-green-600 text-white'
|
||||
}`}
|
||||
title={userRole === 'free' || userRole === 'free_trial' ? 'SVG export is for Pro users' : 'Download SVG'}
|
||||
>
|
||||
{userRole === 'free' || userRole === 'free_trial' ? 'SVG (Pro)' : 'SVG'}
|
||||
@@ -281,7 +285,7 @@ export default function DashboardPage() {
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Link href={/dashboard/edit/ + qr.id} className="flex-1 bg-white border border-gray-300 hover:bg-gray-50 text-gray-700 font-semibold py-2 px-3 rounded-lg transition-colors text-sm text-center">
|
||||
<Link href={`/dashboard/edit/${qr.id}`} className="flex-1 bg-white border border-gray-300 hover:bg-gray-50 text-gray-700 font-semibold py-2 px-3 rounded-lg transition-colors text-sm text-center">
|
||||
Edit Link
|
||||
</Link>
|
||||
|
||||
@@ -359,4 +363,4 @@ export default function DashboardPage() {
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user