mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-10 08:26:19 +02:00
add assets modal
This commit is contained in:
130
src/components/Assets.jsx
Normal file
130
src/components/Assets.jsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import firebase from 'firebase/app';
|
||||||
|
import 'firebase/storage';
|
||||||
|
|
||||||
|
const Assets = () => {
|
||||||
|
const [files, setFiles] = useState([]);
|
||||||
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
|
const [filteredFiles, setFilteredFiles] = useState([]);
|
||||||
|
const storageRef = firebase.storage().ref(`assets/${window.user.uid}`);
|
||||||
|
|
||||||
|
// Function to handle file upload
|
||||||
|
const handleFileUpload = e => {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
|
||||||
|
if (file.size > 5 * 1024 * 1024) {
|
||||||
|
// 5MB limit
|
||||||
|
alert('File size must be less than 5MB');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileRef = storageRef.child(file.name);
|
||||||
|
fileRef
|
||||||
|
.put(file)
|
||||||
|
.then(() => {
|
||||||
|
alert('File uploaded successfully');
|
||||||
|
fetchFiles();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('File upload error:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to fetch existing files
|
||||||
|
const fetchFiles = () => {
|
||||||
|
storageRef
|
||||||
|
.listAll()
|
||||||
|
.then(result => {
|
||||||
|
const filePromises = result.items.map(item => {
|
||||||
|
return item.getDownloadURL().then(url => {
|
||||||
|
return { name: item.name, url };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(filePromises).then(setFiles);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('File fetch error:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to handle search input change
|
||||||
|
const handleSearchChange = e => {
|
||||||
|
const term = e.target.value;
|
||||||
|
setSearchTerm(term);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchFiles();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchTerm) {
|
||||||
|
setFilteredFiles(
|
||||||
|
files.filter(file =>
|
||||||
|
file.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setFilteredFiles(files);
|
||||||
|
}
|
||||||
|
}, [files, searchTerm]);
|
||||||
|
|
||||||
|
const [isDropTarget, setIsDropTarget] = useState(false);
|
||||||
|
const handleDragDropEvent = e => {
|
||||||
|
console.log('drag event, ', e.type);
|
||||||
|
if (e.type === 'dragleave' || e.type === 'drop') {
|
||||||
|
setIsDropTarget(false);
|
||||||
|
}
|
||||||
|
if (e.type === 'dragenter') {
|
||||||
|
setIsDropTarget(true);
|
||||||
|
ode;
|
||||||
|
console.log(999, e.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="asset_manager__upload-box"
|
||||||
|
style={{
|
||||||
|
background: isDropTarget ? '#19a61940' : 'transparent',
|
||||||
|
borderColor: isDropTarget ? 'limegreen' : null
|
||||||
|
}}
|
||||||
|
onDragEnter={handleDragDropEvent}
|
||||||
|
onDragOver={handleDragDropEvent}
|
||||||
|
onDrop={e => {
|
||||||
|
handleDragDropEvent(e);
|
||||||
|
// setFiles(e, 'a');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>Drop file here to upload</p>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
onChange={handleFileUpload}
|
||||||
|
style={{ marginTop: 'auto' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{files.length ? (
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search files"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
<ul>
|
||||||
|
{filteredFiles.map((file, index) => (
|
||||||
|
<li key={index}>
|
||||||
|
<a href={file.url} target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src={file.url} height="20" /> {file.name}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Assets };
|
@ -38,6 +38,17 @@ export function MainHeader(props) {
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
onClick={props.assetsBtnHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="addLibraryButtonClick"
|
||||||
|
data-testid="addLibraryButton"
|
||||||
|
class="btn btn--dark hint--rounded hint--bottom-left"
|
||||||
|
aria-label={i18n._(t`Upload/Use assets`)}
|
||||||
|
>
|
||||||
|
<Trans>Assets</Trans>{' '}
|
||||||
|
</Button>
|
||||||
|
|
||||||
{!props.isFileMode && (
|
{!props.isFileMode && (
|
||||||
<Button
|
<Button
|
||||||
onClick={props.addLibraryBtnHandler}
|
onClick={props.addLibraryBtnHandler}
|
||||||
|
@ -68,6 +68,7 @@ import {
|
|||||||
import { commandPaletteService } from '../commandPaletteService';
|
import { commandPaletteService } from '../commandPaletteService';
|
||||||
|
|
||||||
import { I18nProvider } from '@lingui/react';
|
import { I18nProvider } from '@lingui/react';
|
||||||
|
import { Assets } from './Assets.jsx';
|
||||||
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
@ -113,7 +114,8 @@ export default class App extends Component {
|
|||||||
isOnboardModalOpen: false,
|
isOnboardModalOpen: false,
|
||||||
isJs13KModalOpen: false,
|
isJs13KModalOpen: false,
|
||||||
isCreateNewModalOpen: false,
|
isCreateNewModalOpen: false,
|
||||||
isCommandPaletteOpen: false
|
isCommandPaletteOpen: false,
|
||||||
|
isAssetsOpen: false
|
||||||
};
|
};
|
||||||
this.state = {
|
this.state = {
|
||||||
isSavedItemPaneOpen: false,
|
isSavedItemPaneOpen: false,
|
||||||
@ -526,6 +528,9 @@ export default class App extends Component {
|
|||||||
openAddLibrary() {
|
openAddLibrary() {
|
||||||
this.setState({ isAddLibraryModalOpen: true });
|
this.setState({ isAddLibraryModalOpen: true });
|
||||||
}
|
}
|
||||||
|
assetsBtnClickHandler() {
|
||||||
|
this.setState({ isAssetsOpen: true });
|
||||||
|
}
|
||||||
closeSavedItemsPane() {
|
closeSavedItemsPane() {
|
||||||
this.setState({
|
this.setState({
|
||||||
isSavedItemPaneOpen: false
|
isSavedItemPaneOpen: false
|
||||||
@ -1609,6 +1614,7 @@ export default class App extends Component {
|
|||||||
loginBtnHandler={this.loginBtnClickHandler.bind(this)}
|
loginBtnHandler={this.loginBtnClickHandler.bind(this)}
|
||||||
profileBtnHandler={this.profileBtnClickHandler.bind(this)}
|
profileBtnHandler={this.profileBtnClickHandler.bind(this)}
|
||||||
addLibraryBtnHandler={this.openAddLibrary.bind(this)}
|
addLibraryBtnHandler={this.openAddLibrary.bind(this)}
|
||||||
|
assetsBtnHandler={this.assetsBtnClickHandler.bind(this)}
|
||||||
runBtnClickHandler={this.runBtnClickHandler.bind(this)}
|
runBtnClickHandler={this.runBtnClickHandler.bind(this)}
|
||||||
isFetchingItems={this.state.isFetchingItems}
|
isFetchingItems={this.state.isFetchingItems}
|
||||||
isSaving={this.state.isSaving}
|
isSaving={this.state.isSaving}
|
||||||
@ -1717,6 +1723,12 @@ export default class App extends Component {
|
|||||||
onChange={this.onExternalLibChange.bind(this)}
|
onChange={this.onExternalLibChange.bind(this)}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<Modal
|
||||||
|
show={this.state.isAssetsOpen}
|
||||||
|
closeHandler={() => this.setState({ isAssetsOpen: false })}
|
||||||
|
>
|
||||||
|
<Assets />
|
||||||
|
</Modal>
|
||||||
<Modal
|
<Modal
|
||||||
show={this.state.isNotificationsModalOpen}
|
show={this.state.isNotificationsModalOpen}
|
||||||
closeHandler={() =>
|
closeHandler={() =>
|
||||||
|
@ -2002,6 +2002,15 @@ while the theme CSS file is loading */
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.asset_manager__upload-box {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
border: 3px dashed rgb(255 255 255 / 10%);
|
||||||
|
border-radius: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
transition: 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
body {
|
body {
|
||||||
font-size: 70%;
|
font-size: 70%;
|
||||||
|
Reference in New Issue
Block a user