rafmacalaba commited on
Commit
ac239be
·
1 Parent(s): 9bc1144

Deploy MVP App

Browse files
Files changed (10) hide show
  1. .dockerignore +5 -0
  2. .gitattributes +0 -35
  3. .gitignore +4 -0
  4. Dockerfile +45 -0
  5. README.md +0 -10
  6. app/globals.css +121 -0
  7. app/layout.js +14 -0
  8. app/page.js +69 -0
  9. next.config.mjs +5 -0
  10. package.json +15 -0
.dockerignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ node_modules
2
+ .next
3
+ .git
4
+ .env
5
+ .DS_Store
.gitattributes DELETED
@@ -1,35 +0,0 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .next
2
+ node_modules
3
+ .env
4
+ .DS_Store
Dockerfile ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Base image
2
+ FROM node:18-alpine AS base
3
+
4
+ # Install dependencies only when needed
5
+ FROM base AS deps
6
+ RUN apk add --no-cache libc6-compat
7
+ WORKDIR /app
8
+
9
+ # Copy package.json and install
10
+ COPY package.json ./
11
+ RUN npm install
12
+
13
+ # Rebuild the source code only when needed
14
+ FROM base AS builder
15
+ WORKDIR /app
16
+ COPY --from=deps /app/node_modules ./node_modules
17
+ COPY . .
18
+
19
+ # Build Next.js
20
+ RUN npm run build
21
+
22
+ # Production image, copy all the files and run next
23
+ FROM base AS runner
24
+ WORKDIR /app
25
+
26
+ ENV NODE_ENV production
27
+
28
+ RUN addgroup --system --gid 1001 nodejs
29
+ RUN adduser --system --uid 1001 nextjs
30
+
31
+ # Set the correct permission for prerender cache
32
+ RUN mkdir .next
33
+ RUN chown nextjs:nodejs .next
34
+
35
+ # Automatically leverage output traces to reduce image size
36
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
37
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
38
+
39
+ USER nextjs
40
+
41
+ EXPOSE 7860
42
+ ENV PORT 7860
43
+
44
+ # Next.js standalone server
45
+ CMD ["node", "server.js"]
README.md DELETED
@@ -1,10 +0,0 @@
1
- ---
2
- title: Annotation Mvp
3
- emoji: 🌖
4
- colorFrom: pink
5
- colorTo: indigo
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
app/globals.css ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --bg-color: #0f172a;
3
+ --text-color: #f1f5f9;
4
+ --pane-bg: #1e293b;
5
+ --accent: #3b82f6;
6
+ --accent-hover: #2563eb;
7
+ --border-color: #334155;
8
+ }
9
+
10
+ body {
11
+ margin: 0;
12
+ padding: 0;
13
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
14
+ background-color: var(--bg-color);
15
+ color: var(--text-color);
16
+ display: flex;
17
+ height: 100vh;
18
+ overflow: hidden;
19
+ }
20
+
21
+ h2, h3, h4 {
22
+ margin-top: 0;
23
+ color: #f8fafc;
24
+ }
25
+
26
+ .container {
27
+ display: flex;
28
+ width: 100%;
29
+ height: 100%;
30
+ }
31
+
32
+ .pane {
33
+ flex: 1;
34
+ padding: 24px;
35
+ display: flex;
36
+ flex-direction: column;
37
+ }
38
+
39
+ .left-pane {
40
+ border-right: 1px solid var(--border-color);
41
+ background-color: #020617;
42
+ }
43
+
44
+ .pdf-frame {
45
+ flex-grow: 1;
46
+ width: 100%;
47
+ border: none;
48
+ background: white;
49
+ border-radius: 12px;
50
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
51
+ }
52
+
53
+ .right-pane {
54
+ background-color: var(--pane-bg);
55
+ overflow-y: auto;
56
+ }
57
+
58
+ .markdown-content {
59
+ background-color: #2dd4bf10;
60
+ padding: 24px;
61
+ border-radius: 12px;
62
+ margin-bottom: 24px;
63
+ line-height: 1.6;
64
+ border: 1px solid #2dd4bf30;
65
+ font-size: 1.05rem;
66
+ }
67
+
68
+ .markdown-content hr {
69
+ border: 0;
70
+ height: 1px;
71
+ background: var(--border-color);
72
+ margin: 20px 0;
73
+ }
74
+
75
+ .btn {
76
+ background-color: var(--accent);
77
+ color: #ffffff;
78
+ border: none;
79
+ padding: 12px 20px;
80
+ font-size: 16px;
81
+ border-radius: 8px;
82
+ cursor: pointer;
83
+ font-weight: 600;
84
+ transition: all 0.2s ease;
85
+ box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
86
+ }
87
+
88
+ .btn:hover {
89
+ background-color: var(--accent-hover);
90
+ transform: translateY(-1px);
91
+ }
92
+
93
+ .btn:active {
94
+ transform: translateY(0);
95
+ }
96
+
97
+ .annotations-list {
98
+ margin-top: 32px;
99
+ }
100
+
101
+ .annotations-list ul {
102
+ list-style: none;
103
+ padding: 0;
104
+ margin: 0;
105
+ }
106
+
107
+ .annotations-list li {
108
+ background-color: #33415550;
109
+ padding: 16px;
110
+ margin-bottom: 12px;
111
+ border-radius: 8px;
112
+ border-left: 4px solid #2dd4bf;
113
+ backdrop-filter: blur(4px);
114
+ }
115
+
116
+ .annotations-list small {
117
+ color: #94a3b8;
118
+ display: block;
119
+ margin-top: 8px;
120
+ font-size: 0.8rem;
121
+ }
app/layout.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import './globals.css';
2
+
3
+ export const metadata = {
4
+ title: 'Hugging Face Spaces Annotation App',
5
+ description: 'Minimal MVP for annotation',
6
+ };
7
+
8
+ export default function RootLayout({ children }) {
9
+ return (
10
+ <html lang="en">
11
+ <body>{children}</body>
12
+ </html>
13
+ );
14
+ }
app/page.js ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useState } from 'react';
4
+
5
+ export default function Home() {
6
+ const [annotations, setAnnotations] = useState([]);
7
+
8
+ const handleAnnotate = () => {
9
+ const selection = window.getSelection();
10
+ if (selection && selection.toString().trim() !== "") {
11
+ const selectedText = selection.toString();
12
+ const note = window.prompt("Enter annotation note for: " + selectedText);
13
+ const newAnnotation = {
14
+ text: selectedText,
15
+ note: note || "No note provided",
16
+ timestamp: new Date().toISOString()
17
+ };
18
+ setAnnotations(prev => [...prev, newAnnotation]);
19
+ window.alert("Annotation saved locally! (Simulation)");
20
+ } else {
21
+ window.alert("Please select some text to annotate.");
22
+ }
23
+ };
24
+
25
+ return (
26
+ <div className="container">
27
+ <div className="pane left-pane">
28
+ <h2>PDF Viewer</h2>
29
+ <iframe
30
+ src="https://docs.google.com/viewer?url=https://documents1.worldbank.org/curated/en/776741468181503442/pdf/The-local-socioeconomic-effects-of-gold-mining-evidence-from-Ghana.pdf&embedded=true"
31
+ className="pdf-frame"
32
+ title="Worldbank PDF"
33
+ />
34
+ </div>
35
+ <div className="pane right-pane">
36
+ <h2>Markdown Annotation Mvp</h2>
37
+ <div className="markdown-content">
38
+ <h3>Sample Markdown Data</h3>
39
+ <p>
40
+ Gold mining in Ghana has significant effects on the local socioeconomic environment.
41
+ This case study analyzes those effects comprehensively.
42
+ </p>
43
+ <p>
44
+ You can highlight any text here and click the "Annotate Selection" button below.
45
+ </p>
46
+ <hr />
47
+ <h4>More Context</h4>
48
+ <p>
49
+ We are simulating a list of Markdown formatted texts. Here, annotators could select specific phrases, such as "significant effects", and annotate them with detailed explanations or tags.
50
+ </p>
51
+ </div>
52
+ <button onClick={handleAnnotate} className="btn">Annotate Selection</button>
53
+
54
+ <div className="annotations-list">
55
+ {annotations.length > 0 && <h3>Current Annotations (Session only)</h3>}
56
+ <ul>
57
+ {annotations.map((ann, idx) => (
58
+ <li key={idx}>
59
+ <strong>Selected:</strong> "{ann.text}" <br />
60
+ <strong>Note:</strong> {ann.note} <br />
61
+ <small>{new Date(ann.timestamp).toLocaleString()}</small>
62
+ </li>
63
+ ))}
64
+ </ul>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ );
69
+ }
next.config.mjs ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ output: 'standalone',
4
+ };
5
+ export default nextConfig;
package.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "hf-spaces-annotation-app",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start"
9
+ },
10
+ "dependencies": {
11
+ "next": "14.2.14",
12
+ "react": "^18",
13
+ "react-dom": "^18"
14
+ }
15
+ }