{"id":31827424,"url":"https://github.com/azimonti/progressive-web-app-template-2","last_synced_at":"2026-04-09T21:53:37.117Z","repository":{"id":318441110,"uuid":"1071186560","full_name":"azimonti/progressive-web-app-template-2","owner":"azimonti","description":"A Progressive Web Application (PWA) template featuring local file management and optional Dropbox / Google Drive integration.","archived":false,"fork":false,"pushed_at":"2025-10-07T06:49:52.000Z","size":312,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-07T08:39:42.493Z","etag":null,"topics":["dropbox-sdk","progressive-web-app","pwa","react","vite"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/azimonti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-07T01:54:25.000Z","updated_at":"2025-10-07T06:48:29.000Z","dependencies_parsed_at":"2025-10-07T08:39:44.752Z","dependency_job_id":"eaadee9a-5b1f-45fa-93aa-e029c3d008c8","html_url":"https://github.com/azimonti/progressive-web-app-template-2","commit_stats":null,"previous_names":["azimonti/progressive-web-app-template-2"],"tags_count":2,"template":true,"template_full_name":null,"purl":"pkg:github/azimonti/progressive-web-app-template-2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azimonti%2Fprogressive-web-app-template-2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azimonti%2Fprogressive-web-app-template-2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azimonti%2Fprogressive-web-app-template-2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azimonti%2Fprogressive-web-app-template-2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/azimonti","download_url":"https://codeload.github.com/azimonti/progressive-web-app-template-2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azimonti%2Fprogressive-web-app-template-2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279008283,"owners_count":26084431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dropbox-sdk","progressive-web-app","pwa","react","vite"],"created_at":"2025-10-11T18:28:28.881Z","updated_at":"2025-10-11T18:28:32.648Z","avatar_url":"https://github.com/azimonti.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Progressive Web App Template\n\nA modern **Progressive Web App (PWA)** template built with **Vite**, **React**, **TypeScript**, and **Tailwind CSS v4**.\nDesigned for fast startup, clean structure, and zero config overhead — ideal for creating installable, offline-capable web apps.\n\n---\n\n## 🚀 Stack\n\n| Tool | Purpose |\n|------|----------|\n| [Vite](https://vite.dev) | Lightning-fast development and build tooling |\n| [React](https://react.dev) | UI library |\n| [TypeScript](https://www.typescriptlang.org/) | Static typing |\n| [Tailwind CSS v4](https://tailwindcss.com/) | Utility-first CSS framework (no config required) |\n| [pnpm](https://pnpm.io/) | Fast, disk-efficient package manager |\n\n---\n\n## 🧩 Features\n\n- ⚡ Instant startup with Vite\n- 🎨 Tailwind CSS v4 (config-free setup)\n- 📱 PWA-ready: add manifest and service worker easily\n- 🧱 TypeScript-first React components\n- 🔥 Hot Module Replacement (HMR) out of the box\n- 🧼 Clean, flat project structure (no unnecessary scaffolding)\n- ✨ **Font Awesome** icons ready to use across the UI (brands + solid packs)\n- ☁️ **Full cloud storage integration** with Dropbox and Google Drive\n  - 🔐 Secure OAuth authentication (PKCE for Dropbox, Google Identity Services for Drive)\n  - 🔄 Automatic file synchronization between local and cloud storage\n  - ⚖️ Intelligent conflict resolution for local vs. remote files\n  - 📊 Storage quota management (5MB per file, 50MB total)\n  - 🔁 Token refresh and persistent authentication\n  - 🌐 Cross-platform file access and backup\n\n---\n\n## 🛠️ Setup\n\n```bash\n# Install dependencies\npnpm install\n\n# Start development server\npnpm dev\n\n# Build for production\npnpm build\n\n# Preview production build\npnpm preview\n````\n\nOpen [http://localhost:5173](http://localhost:5173) in your browser.\n\n### UI Icons with Font Awesome\n\n- Font Awesome core is configured in `src/main.tsx` (`config.autoAddCss = false`) and styles are imported once via `@fortawesome/fontawesome-svg-core/styles.css`.\n- Import icons directly where they are used, e.g.\n\n  ```tsx\n  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\n  import { faDropbox } from '@fortawesome/free-brands-svg-icons';\n\n  \u003cFontAwesomeIcon icon={faDropbox} className=\"h-5 w-5 text-sky-500\" /\u003e\n  ```\n\n- The template already uses brand icons for the cloud provider dropdown and solid icons for toast notifications and chevrons. Add additional icons on a per-component basis—no central icon registry is necessary.\n\n### Optional: Cloud Sync\n\nThe template can mirror saved files to a cloud provider. Once configured, use the dropdown in the UI to choose Dropbox or Google Drive and connect.\n\n#### Dropbox\n\n1. Create a scoped Dropbox app in the [Dropbox App Console](https://www.dropbox.com/developers/apps) requesting these permissions: `files.metadata.read`, `files.metadata.write`, `files.content.read`, `files.content.write`.\n2. Add your development URL (e.g. `http://localhost:5173/`) to the app's redirect URIs.\n3. Open `src/services/CloudConfig.ts` and set `DROPBOX_APP_KEY` to your Dropbox app key.\n4. Start the app (`pnpm dev`) and click **Connect Dropbox** to complete the OAuth flow. The redirect URI automatically matches the current origin (e.g. `http://localhost:5173/` or your production URL), so make sure each is added to your Dropbox app configuration.\n\n#### Google Drive\n\n1. Create or reuse a Google Cloud project and [enable the Drive API](https://console.cloud.google.com/apis/library/drive.googleapis.com).\n2. Configure an OAuth 2.0 **Web application** client ID in the Google Cloud Console. Add your dev and production URLs (e.g. `http://localhost:5173/`) to **Authorized JavaScript origins** and **Authorized redirect URIs**.\n3. Open `src/services/CloudConfig.ts` and set `GOOGLE_DRIVE_CLIENT_ID` to your Google OAuth client ID.\n4. (Optional) Adjust `GOOGLE_DRIVE_FOLDER_NAME` in the same file if you want a different target folder.\n5. Start the app (`pnpm dev`) and click **Connect Google Drive**. Sign in with an account that has access to the Drive API for the project.\n\nSynced files are created inside a Drive folder named after `GOOGLE_DRIVE_FOLDER_NAME` (defaults to `pwa-template`) at the root of the user's Drive, so they can be managed manually if needed.\n\n---\n\n## 📦 Directory Structure\n\n```\n.\n├── index.html\n├── postcss.config.js\n├── tsconfig.json\n├── tsconfig.app.json\n├── tsconfig.node.json\n├── vite.config.ts\n├── eslint.config.js\n├── firebase.json\n├── .firebaserc\n├── public/\n│   ├── manifest.webmanifest\n│   ├── sw.js\n│   └── img/\n│       ├── social-card.jpg\n│       └── icons/\n│           ├── pwa-template-32x32.png\n│           ├── pwa-template-180x180.png\n│           ├── pwa-template-192x192.png\n│           ├── pwa-template-512x512-maskable.png\n│           ├── pwa-template-512x512.png\n│           └── pwa-template.ico\n├── src/\n│   ├── App.tsx\n│   ├── main.tsx\n│   ├── index.css\n│   ├── i18n.ts\n│   ├── components/\n│   │   ├── ConfirmationDialog.tsx\n│   │   ├── LanguageSwitcher.tsx\n│   │   └── Toast.tsx\n│   ├── locales/\n│   │   ├── en.json\n│   │   └── ja.json\n│   └── services/\n│       ├── CloudConfig.ts\n│       ├── CloudStorage.ts\n│       ├── DropboxAuthService.ts\n│       ├── DropboxStorageService.ts\n│       ├── FileStorageService.ts\n│       ├── GoogleDriveAuthService.ts\n│       └── GoogleDriveStorageService.ts\n└── package.json\n```\n\n---\n\n## 🧰 PWA Notes\n\nTo make this a full PWA:\n\n1. Add a `manifest.webmanifest` in the project root.\n2. Register a service worker (e.g., using [Workbox](https://developer.chrome.com/docs/workbox)).\n3. Configure Vite’s [PWA plugin](https://vite-pwa-org.netlify.app/).\n\nExample minimal service worker:\n\n```ts\nself.addEventListener('install', () =\u003e self.skipWaiting());\nself.addEventListener('fetch', () =\u003e {});\n```\n\n---\n\n## 🧑‍💻 Author\n\n**Marco Azimonti**\n[https://github.com/azimonti](https://github.com/azimonti)\n\n---\n\n## 🪪 License\n\nThis project is licensed under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazimonti%2Fprogressive-web-app-template-2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazimonti%2Fprogressive-web-app-template-2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazimonti%2Fprogressive-web-app-template-2/lists"}