Compare commits
3 Commits
8cc17a5a17
...
b8e1468a46
| Author | SHA1 | Date | |
|---|---|---|---|
| b8e1468a46 | |||
| 199d92f733 | |||
| d805531369 |
6
.dockerignore
Normal file
6
.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
dist
|
||||
.git
|
||||
.env
|
||||
.DS_Store
|
||||
.claude/
|
||||
@@ -1,12 +1,20 @@
|
||||
name: Build and Release
|
||||
name: Build and Release to Staging
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY_HOST: git.ivanch.me
|
||||
REGISTRY_USERNAME: ivanch
|
||||
IMAGE_NAME: ${{ env.REGISTRY_HOST }}/ivanch/vision-start
|
||||
IMAGE_TAG: staging
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Vision Start
|
||||
if: gitea.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -16,3 +24,47 @@ jobs:
|
||||
run: npm install
|
||||
- name: Run build
|
||||
run: npm run build
|
||||
|
||||
build_vision_start:
|
||||
name: Build Vision Start Image
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to Container Registry
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_PASSWORD }}" \
|
||||
| docker login "${{ env.REGISTRY_HOST }}" \
|
||||
-u "${{ env.REGISTRY_USERNAME }}" \
|
||||
--password-stdin
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and Push Multi-Arch Image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
|
||||
|
||||
deploy_vision_start:
|
||||
name: Deploy Vision Start (staging)
|
||||
runs-on: ubuntu-amd64
|
||||
needs: build_vision_start
|
||||
steps:
|
||||
- name: Recreate Container
|
||||
uses: appleboy/ssh-action@v0.1.7
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
cd ${{ secrets.DIR }}
|
||||
docker compose pull
|
||||
docker compose up -d --force-recreate
|
||||
|
||||
@@ -5,6 +5,12 @@ on:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
env:
|
||||
REGISTRY_HOST: git.ivanch.me
|
||||
REGISTRY_USERNAME: ivanch
|
||||
IMAGE_NAME: ${{ env.REGISTRY_HOST }}/ivanch/vision-start
|
||||
IMAGE_TAG: latest
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -20,7 +26,7 @@ jobs:
|
||||
- name: Run build
|
||||
run: npm run build
|
||||
- name: Prepare release
|
||||
run: |
|
||||
run: |
|
||||
bash scripts/prepare_release.sh
|
||||
mv dist vision-start/
|
||||
mv manifest.json vision-start/
|
||||
@@ -55,15 +61,15 @@ jobs:
|
||||
run: |
|
||||
# Run the VirusTotal check script and capture output
|
||||
bash scripts/check_virustotal.sh > vt_output.txt 2>&1
|
||||
|
||||
|
||||
# Extract analysis URL and detection ratio from output
|
||||
ANALYSIS_URL=$(grep "Analysis URL:" vt_output.txt | cut -d' ' -f3- || echo "Not available")
|
||||
DETECTION_RATIO=$(grep "Detection ratio:" vt_output.txt | cut -d' ' -f3- || echo "Not available")
|
||||
|
||||
|
||||
# Set outputs for next job
|
||||
echo "analysis-url=$ANALYSIS_URL" >> $GITEA_OUTPUT
|
||||
echo "detection-ratio=$DETECTION_RATIO" >> $GITEA_OUTPUT
|
||||
|
||||
|
||||
# Display the full output
|
||||
cat vt_output.txt
|
||||
|
||||
@@ -82,9 +88,53 @@ jobs:
|
||||
with:
|
||||
body: |
|
||||
This is the release for version ${{ gitea.ref_name }}.
|
||||
|
||||
|
||||
**Virus Total Analysis URL:** ${{ needs.virus-total-check.outputs.analysis-url }}
|
||||
**Virus Total Detection Ratio:** ${{ needs.virus-total-check.outputs.detection-ratio }}
|
||||
name: ${{ gitea.ref_name }}
|
||||
tag_name: ${{ gitea.ref_name }}
|
||||
files: vision-start-${{ gitea.ref_name }}.zip
|
||||
files: vision-start-${{ gitea.ref_name }}.zip
|
||||
|
||||
build_vision_start:
|
||||
name: Build Vision Start Image
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to Container Registry
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_PASSWORD }}" \
|
||||
| docker login "${{ env.REGISTRY_HOST }}" \
|
||||
-u "${{ env.REGISTRY_USERNAME }}" \
|
||||
--password-stdin
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and Push Multi-Arch Image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
|
||||
|
||||
deploy_vision_start:
|
||||
name: Deploy Vision Start (production)
|
||||
runs-on: ubuntu-amd64
|
||||
needs: build_vision_start
|
||||
steps:
|
||||
- name: Recreate Container
|
||||
uses: appleboy/ssh-action@v0.1.7
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
cd ${{ secrets.DIR }}
|
||||
docker compose pull
|
||||
docker compose up -d --force-recreate
|
||||
|
||||
1
.gitignore
vendored
Executable file → Normal file
1
.gitignore
vendored
Executable file → Normal file
@@ -11,6 +11,7 @@ node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
.claude/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
|
||||
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
# Build stage
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json and package-lock.json (if available)
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the application
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy the built application from the builder stage
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Start Nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
39
GEMINI.md
Normal file
39
GEMINI.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Vision Startpage Project
|
||||
|
||||
## Overview
|
||||
|
||||
This project is a highly customizable and stylish startpage built with React. The goal is to create a visually appealing and functional dashboard that serves as a user's entry point to the web.
|
||||
|
||||
## Key Features & Design Principles
|
||||
|
||||
* **Technology Stack:** The project is built using React and TypeScript.
|
||||
* **Aesthetics:** The user interface should have a modern, "glassy" or "frosted glass" look (neumorphism/glassmorphism). This involves using transparency, blur effects, and subtle shadows to create a sense of depth.
|
||||
* **Typography:** Specific font families and types will be used to maintain a consistent and elegant design.
|
||||
* **Modals:** All modals in the application should follow a specific and consistent design language, contributing to the overall user experience.
|
||||
* **Production Quality Code:** All code must be written to production standards, with a strong emphasis on readability, maintainability, and performance.
|
||||
* **Creative & Beautiful Code:** Code should not only be functional but also well-structured, elegant, and creative.
|
||||
|
||||
* **Dropdown Component:** A reusable dropdown component (`components/Dropdown.tsx`) has been created for consistent styling and functionality across the application. It features a dark, glassy look with a custom arrow icon.
|
||||
|
||||
**Usage Example:**
|
||||
```typescript jsx
|
||||
import Dropdown from './components/Dropdown';
|
||||
|
||||
// ... inside a React component
|
||||
<Dropdown
|
||||
options={[
|
||||
{ value: 'option1', label: 'Option 1' },
|
||||
{ value: 'option2', label: 'Option 2' },
|
||||
]}
|
||||
value={selectedValue}
|
||||
onChange={handleSelectChange}
|
||||
name="myDropdown"
|
||||
/>
|
||||
```
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
* Follow the existing code style and conventions.
|
||||
* Ensure all new components and features align with the established design principles.
|
||||
* Write clean, commented, and reusable code.
|
||||
* DO NOT run `npm run dev`, and instead, run `npm run build`.
|
||||
0
components/WebsiteTile.tsx
Executable file → Normal file
0
components/WebsiteTile.tsx
Executable file → Normal file
0
constants.tsx
Executable file → Normal file
0
constants.tsx
Executable file → Normal file
0
icon.png
Executable file → Normal file
0
icon.png
Executable file → Normal file
|
Before Width: | Height: | Size: 763 KiB After Width: | Height: | Size: 763 KiB |
0
index.html
Executable file → Normal file
0
index.html
Executable file → Normal file
57
notes-widget-plan.md
Normal file
57
notes-widget-plan.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Notes Widget Implementation Plan
|
||||
## Overview
|
||||
This document outlines the implementation plan for a Notes / Scratchpad Widget feature that:
|
||||
1. Provides a text area that saves content to local storage automatically
|
||||
2. Includes bold and italic formatting buttons
|
||||
3. Has a toggle icon to show/hide the widget
|
||||
4. Has a glassy/frosty design with strong blur
|
||||
## Implementation Steps
|
||||
### 1. Update Config Interface
|
||||
In `types.ts`, add a new `notesWidget` configuration object:
|
||||
```typescript
|
||||
notesWidget: {
|
||||
enabled: boolean;
|
||||
}
|
||||
```
|
||||
### 2. Update ConfigurationModal Component
|
||||
In `components/ConfigurationModal.tsx`:
|
||||
- Add `notesWidget` to the config state initialization (lines 18-44)
|
||||
- Add a new "Notes" tab to the tab navigation (lines 259-284)
|
||||
- Add a toggle switch for notesWidget.enabled in the Notes tab (lines 552-560)
|
||||
- Add the Notes tab content with the toggle switch
|
||||
### 3. Create NotesWidget Component
|
||||
Create a new file `components/NotesWidget.tsx`:
|
||||
- Text area for notes input
|
||||
- Bold and italic formatting buttons
|
||||
- Toggle icon for showing/hiding the widget
|
||||
- Glassy/frosty design with strong blur
|
||||
- Auto-save to localStorage using `userNotes` key
|
||||
### 4. Update App Component
|
||||
In `App.tsx`:
|
||||
- Add notesWidget to the defaultConfig (lines 14-35)
|
||||
- Add the NotesWidget component to the render output when enabled in config (lines 250-251)
|
||||
- Add logic to save/load notes from localStorage
|
||||
## Technical Details
|
||||
### Configuration Structure
|
||||
The configuration will be stored in the same way as other widgets:
|
||||
```typescript
|
||||
config: {
|
||||
notesWidget: {
|
||||
enabled: boolean;
|
||||
}
|
||||
}
|
||||
```
|
||||
### Local Storage Key
|
||||
All notes text will be saved to localStorage with the key `userNotes`.
|
||||
### UI Design
|
||||
- Widget will be positioned on the left side of the screen
|
||||
- Vertically centered using flexbox
|
||||
- Glassy/frosty design using backdrop-blur and background transparency
|
||||
- Strong blur effect (backdrop-blur-2xl or similar)
|
||||
- Toggle icon will be positioned on the left edge of the widget
|
||||
- When hidden, icon shows a "show" indicator
|
||||
- When open, icon shows a "hide" indicator
|
||||
### Formatting Buttons
|
||||
- Bold button (B)
|
||||
- Italic button (I)
|
||||
- These will use HTML formatting (bold/italic tags) or rich text approach
|
||||
0
package.json
Executable file → Normal file
0
package.json
Executable file → Normal file
0
public/favicon.ico
Executable file → Normal file
0
public/favicon.ico
Executable file → Normal file
|
Before Width: | Height: | Size: 763 KiB After Width: | Height: | Size: 763 KiB |
0
scripts/check_virustotal.sh
Executable file → Normal file
0
scripts/check_virustotal.sh
Executable file → Normal file
0
tsconfig.json
Executable file → Normal file
0
tsconfig.json
Executable file → Normal file
0
vite.config.ts
Executable file → Normal file
0
vite.config.ts
Executable file → Normal file
Reference in New Issue
Block a user