Twan07 commited on
Commit
16e3470
·
verified ·
1 Parent(s): 4f19cf0

Upload 9 files

Browse files
Files changed (9) hide show
  1. App.tsx +140 -0
  2. README.md +20 -10
  3. index.html +71 -0
  4. index.tsx +15 -0
  5. metadata.json +5 -0
  6. package.json +29 -0
  7. tsconfig.json +20 -0
  8. types.ts +31 -0
  9. vite.config.ts +6 -0
App.tsx ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { UploadStatus } from './types';
3
+ import { FileUploader } from './components/FileUploader';
4
+ import { UploadList } from './components/UploadList';
5
+ import { Upload, Rocket, Database, ShieldCheck, Zap, LayoutGrid } from 'lucide-react';
6
+ import { useFileUpload } from './hooks/useFileUpload';
7
+
8
+ export default function App() {
9
+ const {
10
+ files,
11
+ isUploading,
12
+ addFiles,
13
+ removeFile,
14
+ updateFilePath,
15
+ startUpload
16
+ } = useFileUpload();
17
+
18
+ const hasPendingFiles = files.some(f => f.status === UploadStatus.IDLE || f.status === UploadStatus.ERROR);
19
+
20
+ return (
21
+ <div className="min-h-screen bg-gray-50 flex flex-col font-sans">
22
+ {/* Header */}
23
+ <header className="bg-white border-b border-gray-200 sticky top-0 z-20 shadow-sm">
24
+ <div className="max-w-5xl mx-auto px-6 py-4 flex items-center justify-between">
25
+ <div className="flex items-center gap-3">
26
+ <div className="bg-gradient-to-br from-yellow-400 to-orange-500 p-2.5 rounded-xl shadow-md">
27
+ <Rocket className="w-6 h-6 text-white" />
28
+ </div>
29
+ <div>
30
+ <h1 className="text-xl font-bold text-gray-900 leading-tight tracking-tight">DataTwan Uploader</h1>
31
+ <p className="text-xs text-gray-500 font-medium flex items-center gap-1.5">
32
+ <span className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
33
+ Secure Connection Active
34
+ </p>
35
+ </div>
36
+ </div>
37
+ <div className="flex items-center gap-4">
38
+ <nav className="hidden md:flex items-center gap-6 text-sm font-medium text-gray-600">
39
+ <a href="#features" className="hover:text-yellow-600 transition-colors">Features</a>
40
+ <a href="#about" className="hover:text-yellow-600 transition-colors">About</a>
41
+ </nav>
42
+ </div>
43
+ </div>
44
+ </header>
45
+
46
+ {/* Main Content */}
47
+ <main className="flex-grow w-full max-w-3xl mx-auto px-6 py-12 space-y-8">
48
+
49
+ {/* Intro */}
50
+ <section className="text-center mb-10">
51
+ <h2 className="text-3xl font-extrabold text-gray-900 mb-4">
52
+ Upload Datasets to Hugging Face
53
+ </h2>
54
+ <p className="text-gray-600 text-lg leading-relaxed">
55
+ The fastest, most secure way to manage your machine learning datasets.
56
+ Bulk upload files directly to the <strong>DataTwan</strong> repository.
57
+ </p>
58
+ </section>
59
+
60
+ {/* Upload Area */}
61
+ <div className="bg-white p-1 rounded-2xl shadow-sm border border-gray-200">
62
+ <div className="p-8">
63
+ <h3 className="text-lg font-semibold text-gray-800 flex items-center gap-2 mb-6">
64
+ <Upload className="w-5 h-5 text-blue-500" />
65
+ Select Dataset Files
66
+ </h3>
67
+ <FileUploader
68
+ onFilesAdded={addFiles}
69
+ disabled={isUploading}
70
+ />
71
+ </div>
72
+ </div>
73
+
74
+ {/* File Queue */}
75
+ <div id="queue">
76
+ <UploadList
77
+ files={files}
78
+ onRemove={removeFile}
79
+ onPathChange={updateFilePath}
80
+ />
81
+ </div>
82
+
83
+ {/* Upload Action */}
84
+ {files.length > 0 && (
85
+ <div className="flex justify-end pt-2">
86
+ <button
87
+ onClick={startUpload}
88
+ disabled={!hasPendingFiles || isUploading}
89
+ className={`
90
+ flex items-center gap-2 px-10 py-4 rounded-xl font-bold shadow-lg transform transition-all text-lg
91
+ ${!hasPendingFiles || isUploading
92
+ ? 'bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200'
93
+ : 'bg-gradient-to-r from-yellow-400 to-orange-500 text-white hover:shadow-orange-200 hover:shadow-xl hover:-translate-y-0.5 active:translate-y-0'}
94
+ `}
95
+ >
96
+ {isUploading ? (
97
+ <>
98
+ <Rocket className="w-6 h-6 animate-pulse" />
99
+ Uploading...
100
+ </>
101
+ ) : (
102
+ <>
103
+ <Upload className="w-6 h-6" />
104
+ Start Secure Upload
105
+ </>
106
+ )}
107
+ </button>
108
+ </div>
109
+ )}
110
+ </main>
111
+
112
+ {/* SEO Footer */}
113
+ <footer className="bg-white border-t border-gray-200 mt-12 py-12">
114
+ <div className="max-w-5xl mx-auto px-6 grid md:grid-cols-2 gap-12">
115
+ <article id="about" className="space-y-4">
116
+ <h3 className="text-lg font-bold text-gray-900 flex items-center gap-2">
117
+ <Database className="w-5 h-5 text-yellow-500" />
118
+ About DataTwan Uploader
119
+ </h3>
120
+ <p className="text-gray-600 text-sm leading-relaxed">
121
+ DataTwan Uploader is a premier <strong>Hugging Face Dataset Management Tool</strong>.
122
+ We streamline pushing large datasets to the cloud with enterprise-grade reliability.
123
+ </p>
124
+ </article>
125
+ <article id="features" className="space-y-4">
126
+ <h3 className="text-lg font-bold text-gray-900 flex items-center gap-2">
127
+ <Zap className="w-5 h-5 text-yellow-500" />
128
+ Features
129
+ </h3>
130
+ <ul className="space-y-3 text-sm text-gray-600">
131
+ <li className="flex gap-2 items-center"><ShieldCheck className="w-4 h-4 text-green-500"/> Secure Proxy Upload Technology</li>
132
+ <li className="flex gap-2 items-center"><LayoutGrid className="w-4 h-4 text-blue-500"/> Bulk File Processing</li>
133
+ <li className="flex gap-2 items-center"><Rocket className="w-4 h-4 text-orange-500"/> Optimized for High Performance</li>
134
+ </ul>
135
+ </article>
136
+ </div>
137
+ </footer>
138
+ </div>
139
+ );
140
+ }
README.md CHANGED
@@ -1,10 +1,20 @@
1
- ---
2
- title: Testupload
3
- emoji: 🐨
4
- colorFrom: blue
5
- colorTo: green
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+ <img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
3
+ </div>
4
+
5
+ # Run and deploy your AI Studio app
6
+
7
+ This contains everything you need to run your app locally.
8
+
9
+ View your app in AI Studio: https://ai.studio/apps/drive/1ze_cSnjsTlEMs0ohdHMtGIuvNxtA4x4w
10
+
11
+ ## Run Locally
12
+
13
+ **Prerequisites:** Node.js
14
+
15
+
16
+ 1. Install dependencies:
17
+ `npm install`
18
+ 2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
19
+ 3. Run the app:
20
+ `npm run dev`
index.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+
7
+ <!-- Primary SEO Meta Tags -->
8
+ <title>DataTwan - Free Hugging Face Dataset Uploader & Manager</title>
9
+ <meta name="description" content="Upload datasets efficiently to Hugging Face with DataTwan. A fast, secure, and free tool for managing machine learning datasets. Support for bulk uploads directly to DataTwan repositories." />
10
+ <meta name="keywords" content="Hugging Face uploader, dataset upload, DataTwan, machine learning datasets, AI data management, bulk file upload, Hugging Face API" />
11
+ <meta name="author" content="DataTwan" />
12
+ <meta name="robots" content="index, follow" />
13
+
14
+ <!-- Open Graph / Facebook -->
15
+ <meta property="og:type" content="website" />
16
+ <meta property="og:url" content="https://datatwan-uploader.com/" />
17
+ <meta property="og:title" content="DataTwan - Hugging Face Dataset Uploader" />
18
+ <meta property="og:description" content="The easiest way to upload and manage datasets on Hugging Face. Secure, fast, and optimized for ML workflows." />
19
+ <meta property="og:site_name" content="DataTwan Uploader" />
20
+
21
+ <!-- Twitter -->
22
+ <meta property="twitter:card" content="summary_large_image" />
23
+ <meta property="twitter:title" content="DataTwan - Hugging Face Dataset Uploader" />
24
+ <meta property="twitter:description" content="Upload datasets efficiently to Hugging Face with DataTwan. Secure and fast bulk uploading." />
25
+
26
+ <!-- Structured Data for Google (JSON-LD) -->
27
+ <script type="application/ld+json">
28
+ {
29
+ "@context": "https://schema.org",
30
+ "@type": "WebApplication",
31
+ "name": "DataTwan Uploader",
32
+ "url": "https://datatwan-uploader.com",
33
+ "description": "A professional tool to upload files directly to Hugging Face repositories.",
34
+ "applicationCategory": "DeveloperApplication",
35
+ "operatingSystem": "Any browser",
36
+ "offers": {
37
+ "@type": "Offer",
38
+ "price": "0",
39
+ "priceCurrency": "USD"
40
+ },
41
+ "featureList": "Bulk upload, Hugging Face Integration, Dataset Management"
42
+ }
43
+ </script>
44
+
45
+ <script src="https://cdn.tailwindcss.com"></script>
46
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
47
+ <style>
48
+ body {
49
+ font-family: 'Inter', sans-serif;
50
+ }
51
+ </style>
52
+ <script type="importmap">
53
+ {
54
+ "imports": {
55
+ "react/": "https://aistudiocdn.com/react@^19.2.0/",
56
+ "react": "https://aistudiocdn.com/react@^19.2.0",
57
+ "react-dom/": "https://aistudiocdn.com/react-dom@^19.2.0/",
58
+ "lucide-react": "https://aistudiocdn.com/lucide-react@^0.555.0",
59
+ "vite": "https://aistudiocdn.com/vite@^7.2.4",
60
+ "@vitejs/plugin-react": "https://aistudiocdn.com/@vitejs/plugin-react@^5.1.1",
61
+ "@huggingface/hub": "https://aistudiocdn.com/@huggingface/hub@^2.7.1"
62
+ }
63
+ }
64
+ </script>
65
+ <link rel="stylesheet" href="/index.css">
66
+ </head>
67
+ <body class="bg-gray-50 text-gray-900 antialiased flex flex-col min-h-screen">
68
+ <div id="root" class="flex-grow"></div>
69
+ <script type="module" src="/index.tsx"></script>
70
+ </body>
71
+ </html>
index.tsx ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+
5
+ const rootElement = document.getElementById('root');
6
+ if (!rootElement) {
7
+ throw new Error("Could not find root element to mount to");
8
+ }
9
+
10
+ const root = ReactDOM.createRoot(rootElement);
11
+ root.render(
12
+ <React.StrictMode>
13
+ <App />
14
+ </React.StrictMode>
15
+ );
metadata.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "name": "HF Hub Uploader",
3
+ "description": "A professional tool to upload files directly to Hugging Face repositories using the @huggingface/hub library.",
4
+ "requestFramePermissions": []
5
+ }
package.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "datatwan-uploader",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "react": "^18.2.0",
13
+ "react-dom": "^18.2.0",
14
+ "lucide-react": "^0.344.0",
15
+ "@huggingface/hub": "^0.15.1",
16
+ "clsx": "^2.1.0",
17
+ "tailwind-merge": "^2.2.1"
18
+ },
19
+ "devDependencies": {
20
+ "@types/react": "^18.2.64",
21
+ "@types/react-dom": "^18.2.21",
22
+ "@vitejs/plugin-react": "^4.2.1",
23
+ "autoprefixer": "^10.4.18",
24
+ "postcss": "^8.4.35",
25
+ "tailwindcss": "^3.4.1",
26
+ "typescript": "^5.2.2",
27
+ "vite": "^5.1.4"
28
+ }
29
+ }
tsconfig.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": false,
16
+ "noUnusedParameters": false,
17
+ "noFallthroughCasesInSwitch": true
18
+ },
19
+ "include": ["**/*.ts", "**/*.tsx"]
20
+ }
types.ts ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export type RepoType = 'model' | 'dataset' | 'space';
2
+
3
+ export interface HFConfig {
4
+ token: string;
5
+ repo: string;
6
+ repoType: RepoType;
7
+ }
8
+
9
+ export enum UploadStatus {
10
+ IDLE = 'IDLE',
11
+ UPLOADING = 'UPLOADING',
12
+ SUCCESS = 'SUCCESS',
13
+ ERROR = 'ERROR',
14
+ }
15
+
16
+ export interface FileItem {
17
+ id: string;
18
+ file: File;
19
+ status: UploadStatus;
20
+ path: string; // Destination path in repo
21
+ error?: string;
22
+ url?: string; // URL to the file after upload
23
+ }
24
+
25
+ export interface RemoteFile {
26
+ path: string;
27
+ size: number;
28
+ url: string;
29
+ }
30
+
31
+ export type UploadCallback = (id: string, status: UploadStatus, error?: string, url?: string) => void;
vite.config.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ });