Skip to content

Commit fa42552

Browse files
Merge pull request #1 from solid/feat-file-manager
feat: basic frontend ui
2 parents 1bd42d9 + cab1118 commit fa42552

10 files changed

Lines changed: 1217 additions & 88 deletions

File tree

README.md

Lines changed: 137 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,154 @@
1-
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
1+
# Solid File Manager
2+
3+
A Google Drive-like file manager for Solid Pods, built with Next.js, React, and TypeScript.
4+
5+
## Overview
6+
7+
This application provides a user-friendly interface for managing files and folders in Solid Pods, with features similar to Google Drive:
8+
9+
- **File Management**: Browse, view, and organize files and folders
10+
- **Permission Management**: Share files with others using ACP (Access Control Policies) with a Google Drive-like interface
11+
- **Multiple Drives**: View and manage multiple storage roots/drives
12+
- **Grid and List Views**: Toggle between grid and list views for file browsing
13+
- **Search**: Search functionality for finding files quickly
14+
15+
## Features
16+
17+
### Current UI Features (Phase 1)
18+
19+
- ✅ Google Drive-like interface layout
20+
- ✅ Left sidebar with drives list
21+
- ✅ Main content area with file list
22+
- ✅ Grid and list view toggle
23+
- ✅ Breadcrumb navigation
24+
- ✅ File item display with icons and metadata
25+
- ✅ Permissions/sharing dialog (UI only)
26+
- ✅ Minimal black, white, and light purple color scheme
27+
- ✅ Semantic HTML for accessibility
28+
29+
### Planned Features (Phase 2 - Integration)
30+
31+
- [ ] Solid authentication (OIDC)
32+
- [ ] File operations (create, read, update, delete)
33+
- [ ] Folder navigation
34+
- [ ] ACP permission management integration
35+
- [ ] Storage root discovery from WebID
36+
- [ ] File upload/download
37+
- [ ] Real-time file updates
38+
39+
## Tech Stack
40+
41+
- **Framework**: Next.js 16
42+
- **UI Library**: React 19
43+
- **Styling**: Tailwind CSS 4
44+
- **Language**: TypeScript
45+
- **Solid SDK**: [@inrupt/solid-client-js](https://github.com/inrupt/solid-client-js) (to be integrated)
246

347
## Getting Started
448

5-
First, run the development server:
49+
### Prerequisites
50+
51+
- Node.js 18+
52+
- npm, yarn, pnpm, or bun
53+
54+
### Installation
55+
56+
1. Clone the repository:
57+
```bash
58+
git clone <repository-url>
59+
cd solid-file-manager
60+
```
61+
62+
2. Install dependencies:
63+
```bash
64+
npm install
65+
```
666

67+
3. Run the development server:
768
```bash
869
npm run dev
9-
# or
10-
yarn dev
11-
# or
12-
pnpm dev
13-
# or
14-
bun dev
1570
```
1671

17-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
72+
4. Open [http://localhost:3000](http://localhost:3000) in your browser.
73+
74+
## Development Setup
75+
76+
### Local CSS (Community Solid Server)
77+
78+
For development, you'll need to run a local Community Solid Server (CSS). The app is configured to work with a CSS instance running on `http://localhost:3001/`.
79+
80+
### Environment Variables
81+
82+
Create a `.env.local` file in the root directory:
83+
84+
```env
85+
# The URI of the Solid container used by the demo Community Solid Server
86+
# Default for local dev (Community Solid Server started by `npm run start:css`)
87+
NEXT_PUBLIC_BASE_URI="http://localhost:3001/"
88+
89+
# The manifest resource file used by the app (relative to the container root)
90+
NEXT_PUBLIC_MANIFEST_RESOURCE_URI="resource.ttl"
91+
92+
# Admin WebID used for booting the demo (replace with your WebID)
93+
NEXT_PUBLIC_ADMIN_WEBID="https://id.inrupt.com/your-webid"
94+
95+
NEXT_PUBLIC_OIDC_ISSUER="https://login.inrupt.com"
96+
```
97+
98+
## Project Structure
99+
100+
```
101+
solid-file-manager/
102+
├── app/
103+
│ ├── components/ # React components
104+
│ │ ├── Header.tsx # Top header with search and actions
105+
│ │ ├── Sidebar.tsx # Left sidebar with drives list
106+
│ │ ├── Breadcrumb.tsx # Navigation breadcrumb
107+
│ │ ├── FileList.tsx # Main file list component
108+
│ │ ├── FileItem.tsx # Individual file/folder item
109+
│ │ └── PermissionsDialog.tsx # Sharing/permissions dialog
110+
│ ├── page.tsx # Main page component
111+
│ ├── layout.tsx # Root layout
112+
│ └── globals.css # Global styles
113+
├── public/ # Static assets
114+
└── README.md
115+
```
116+
117+
## Solid Protocol Integration
118+
119+
This application will integrate with Solid using:
120+
121+
- **Solid Protocol**: [https://solidproject.org/TR/protocol#resources](https://solidproject.org/TR/protocol#resources)
122+
- **ACP (Access Control Policies)**: [https://solid.github.io/authorization-panel/acp-specification/](https://solid.github.io/authorization-panel/acp-specification/)
123+
- **Storage Root Discovery**: Using `pim:storage` predicate from WebID
124+
- **SDK**: [@inrupt/solid-client-js](https://github.com/inrupt/solid-client-js)
125+
126+
## Design Principles
18127

19-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
128+
- **Minimal Design**: Black, white, and light purple color scheme with no gradients
129+
- **Accessibility**: Semantic HTML and ARIA labels throughout
130+
- **Code Splitting**: Components are split into reusable, focused modules
131+
- **Type Safety**: Full TypeScript support for type safety
20132

21-
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
133+
## Contributing
22134

23-
## Learn More
135+
This project is currently in active development. The UI phase is complete, and Solid integration is the next step.
24136

25-
To learn more about Next.js, take a look at the following resources:
137+
## License
26138

27-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
139+
[Add your license here]
29140

30-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
141+
## References
31142

32-
## Deploy on Vercel
143+
- [Solid Project](https://solidproject.org/)
144+
- [Solid Protocol Specification](https://solidproject.org/TR/protocol)
145+
- [ACP Specification](https://solid.github.io/authorization-panel/acp-specification/)
146+
- [Inrupt Solid Client JS](https://github.com/inrupt/solid-client-js)
147+
- [Community Solid Server](https://github.com/CommunitySolidServer/CommunitySolidServer)
33148

34-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
149+
## Related Projects
35150

36-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
151+
- [nextfm](https://github.com/inrupt/nextfm)
152+
- [Penny](https://penny.vincenttunru.com/)
153+
- [PodPro](https://podpro.dev/)
154+
- [solid-filemanager](https://otto-aa.github.io/solid-filemanager/)

app/components/Breadcrumb.tsx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"use client";
2+
3+
interface BreadcrumbItem {
4+
name: string;
5+
path: string;
6+
}
7+
8+
interface BreadcrumbProps {
9+
items: BreadcrumbItem[];
10+
onNavigate: (path: string) => void;
11+
}
12+
13+
export default function Breadcrumb({ items, onNavigate }: BreadcrumbProps) {
14+
// On mobile, show only the last item or truncate
15+
const displayItems = items.length > 2 ? [items[0], ...items.slice(-2)] : items;
16+
17+
return (
18+
<nav className="flex items-center gap-1 overflow-x-auto px-2 py-2 sm:gap-2 sm:px-4" aria-label="Breadcrumb">
19+
<ol className="flex min-w-0 items-center gap-1 sm:gap-2" role="list">
20+
{items.length > 2 && (
21+
<>
22+
<li className="flex items-center gap-1 sm:gap-2">
23+
<button
24+
type="button"
25+
onClick={() => onNavigate(items[0].path)}
26+
className="cursor-pointer truncate text-sm text-gray-600 hover:text-black"
27+
>
28+
{items[0].name}
29+
</button>
30+
<svg
31+
className="h-4 w-4 flex-shrink-0 text-gray-400"
32+
fill="none"
33+
stroke="currentColor"
34+
viewBox="0 0 24 24"
35+
aria-hidden="true"
36+
>
37+
<path
38+
strokeLinecap="round"
39+
strokeLinejoin="round"
40+
strokeWidth={2}
41+
d="M9 5l7 7-7 7"
42+
/>
43+
</svg>
44+
</li>
45+
<li className="text-sm text-gray-400">...</li>
46+
</>
47+
)}
48+
{displayItems.slice(items.length > 2 ? 1 : 0).map((item, index) => {
49+
const actualIndex = items.length > 2 ? items.length - 2 + index : index;
50+
return (
51+
<li key={item.path} className="flex items-center gap-1 sm:gap-2">
52+
{actualIndex > 0 && (
53+
<svg
54+
className="h-4 w-4 flex-shrink-0 text-gray-400"
55+
fill="none"
56+
stroke="currentColor"
57+
viewBox="0 0 24 24"
58+
aria-hidden="true"
59+
>
60+
<path
61+
strokeLinecap="round"
62+
strokeLinejoin="round"
63+
strokeWidth={2}
64+
d="M9 5l7 7-7 7"
65+
/>
66+
</svg>
67+
)}
68+
<button
69+
type="button"
70+
onClick={() => onNavigate(item.path)}
71+
className={`cursor-pointer truncate text-sm ${
72+
actualIndex === items.length - 1
73+
? "font-medium text-black"
74+
: "text-gray-600 hover:text-black"
75+
}`}
76+
aria-current={actualIndex === items.length - 1 ? "page" : undefined}
77+
>
78+
{item.name}
79+
</button>
80+
</li>
81+
);
82+
})}
83+
</ol>
84+
</nav>
85+
);
86+
}
87+

0 commit comments

Comments
 (0)