@jhits/plugin-images 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +47 -0
- package/src/api/fallback/route.ts +69 -0
- package/src/api/index.ts +10 -0
- package/src/api/list/index.ts +96 -0
- package/src/api/resolve/route.ts +122 -0
- package/src/api/router.ts +85 -0
- package/src/api/upload/index.ts +88 -0
- package/src/api/uploads/[filename]/route.ts +93 -0
- package/src/api-server.ts +11 -0
- package/src/assets/noimagefound.jpg +0 -0
- package/src/components/BackgroundImage.tsx +111 -0
- package/src/components/GlobalImageEditor.tsx +778 -0
- package/src/components/Image.tsx +177 -0
- package/src/components/ImagePicker.tsx +541 -0
- package/src/components/ImagesPluginInit.tsx +31 -0
- package/src/components/index.ts +7 -0
- package/src/config.ts +179 -0
- package/src/index.server.ts +11 -0
- package/src/index.tsx +56 -0
- package/src/init.tsx +58 -0
- package/src/types/index.ts +60 -0
- package/src/utils/fallback.ts +73 -0
- package/src/views/ImageManager.tsx +30 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useState, useEffect } from 'react';
|
|
4
|
+
import { Image } from './Image';
|
|
5
|
+
import { Edit2, Loader2 } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
export interface BackgroundImageProps {
|
|
8
|
+
id: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
style?: React.CSSProperties;
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
backgroundSize?: 'cover' | 'contain' | 'auto' | string;
|
|
13
|
+
backgroundPosition?: string;
|
|
14
|
+
backgroundRepeat?: 'repeat' | 'no-repeat' | 'repeat-x' | 'repeat-y';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* BackgroundImage Component
|
|
19
|
+
* * A container that handles a background image with admin edit capabilities.
|
|
20
|
+
* The edit button appears on hover anywhere within the container.
|
|
21
|
+
*/
|
|
22
|
+
export function BackgroundImage({
|
|
23
|
+
id,
|
|
24
|
+
className = '',
|
|
25
|
+
style = {},
|
|
26
|
+
children,
|
|
27
|
+
backgroundSize = 'cover',
|
|
28
|
+
backgroundPosition = 'center',
|
|
29
|
+
}: BackgroundImageProps) {
|
|
30
|
+
const [isAdmin, setIsAdmin] = useState(false);
|
|
31
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
32
|
+
|
|
33
|
+
// Authentication check for Admin/Dev users
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const checkUser = async () => {
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch('/api/me');
|
|
38
|
+
const data = await res.json();
|
|
39
|
+
if (data.loggedIn && (data.user?.role === 'admin' || data.user?.role === 'dev')) {
|
|
40
|
+
setIsAdmin(true);
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error('Failed to check user role:', error);
|
|
44
|
+
} finally {
|
|
45
|
+
setIsLoading(false);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
checkUser();
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const handleEditClick = (e: React.MouseEvent) => {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
e.stopPropagation();
|
|
54
|
+
// Dispatch event to the GlobalImageEditor
|
|
55
|
+
window.dispatchEvent(new CustomEvent('open-image-editor', { detail: { id } }));
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div
|
|
60
|
+
data-background-image-component="true"
|
|
61
|
+
data-background-image-id={id}
|
|
62
|
+
className={`group relative overflow-hidden w-full ${className}`}
|
|
63
|
+
style={style}
|
|
64
|
+
>
|
|
65
|
+
{/* 1. BACKGROUND IMAGE LAYER (z-0) */}
|
|
66
|
+
<div className="absolute inset-0 z-0 pointer-events-none">
|
|
67
|
+
<Image
|
|
68
|
+
id={id}
|
|
69
|
+
alt=""
|
|
70
|
+
fill
|
|
71
|
+
className="w-full h-full"
|
|
72
|
+
objectFit={backgroundSize === 'cover' ? 'cover' : 'contain'}
|
|
73
|
+
objectPosition={backgroundPosition}
|
|
74
|
+
editable={false} // We handle the button manually below
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{/* 2. CONTENT LAYER (z-10) */}
|
|
79
|
+
<div className="relative z-10 w-full h-full">
|
|
80
|
+
{children}
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
{/* 3. ADMIN UI LAYER (z-50) - Dashboard Theme */}
|
|
84
|
+
{!isLoading && isAdmin && (
|
|
85
|
+
<div className="absolute inset-0 z-50 pointer-events-none">
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
onClick={handleEditClick}
|
|
89
|
+
className="
|
|
90
|
+
pointer-events-auto absolute bottom-8 left-8
|
|
91
|
+
flex items-center gap-3 px-6 py-3
|
|
92
|
+
bg-neutral-100 dark:bg-neutral-800
|
|
93
|
+
text-neutral-900 dark:text-neutral-100
|
|
94
|
+
rounded-full shadow-2xl
|
|
95
|
+
border border-neutral-300 dark:border-neutral-700
|
|
96
|
+
cursor-pointer hover:bg-neutral-200 dark:hover:bg-neutral-700
|
|
97
|
+
opacity-0 group-hover:opacity-100
|
|
98
|
+
translate-y-4 group-hover:translate-y-0
|
|
99
|
+
transition-all duration-500 ease-out
|
|
100
|
+
"
|
|
101
|
+
>
|
|
102
|
+
<Edit2 size={16} strokeWidth={2.5} className="text-primary" />
|
|
103
|
+
<span className="text-[11px] font-black uppercase tracking-[0.2em]">
|
|
104
|
+
Edit Background
|
|
105
|
+
</span>
|
|
106
|
+
</button>
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|