Skip to content

Commit 4c0538e

Browse files
committed
add bug report / feature request feature
1 parent 0bb5fe9 commit 4c0538e

File tree

7 files changed

+510
-18
lines changed

7 files changed

+510
-18
lines changed

.env.local.example

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,14 @@ GOOGLE_AI_TEXT_API_KEY=your_google_ai_text_api_key_here
1010
# Google Analytics Measurement ID
1111
# Get this from your Google Analytics 4 property settings
1212
# Format: G-XXXXXXXXXX
13-
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
13+
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
14+
15+
# GitHub Personal Access Token for creating issues via repository dispatch
16+
# Required scope: public_repo (or repo for private repositories)
17+
# Get your PAT from https://github.com/settings/tokens
18+
GITHUB_PAT=ghp_xxxxxxxxxxxxxxxxxxxx
19+
20+
# Optional: Override the default GitHub repository owner and name
21+
# Defaults to 'victorhuangwq' and 'story-to-manga' if not specified
22+
# GITHUB_OWNER=victorhuangwq
23+
# GITHUB_REPO=story-to-manga

.github/workflows/create-issue.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Create Issue from User Report
2+
3+
on:
4+
repository_dispatch:
5+
types: [create-issue]
6+
7+
jobs:
8+
create-issue:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Create Issue
12+
uses: actions/github-script@v8
13+
with:
14+
script: |
15+
const { type, description, user_agent, timestamp } = context.payload.client_payload;
16+
17+
const title = `[${type === 'bug' ? 'Bug Report' : 'Feature Request'}] User submitted report`;
18+
19+
const labels = type === 'bug' ? ['bug', 'user-reported'] : ['enhancement', 'user-reported'];
20+
21+
const body = `## Type
22+
${type === 'bug' ? '🐛 Bug Report' : '✨ Feature Request'}
23+
24+
## Description
25+
${description}
26+
27+
## Metadata
28+
- **Submitted at:** ${timestamp}
29+
- **User Agent:** ${user_agent}
30+
31+
---
32+
*This issue was automatically created from a user submission via the web form.*`;
33+
34+
await github.rest.issues.create({
35+
owner: context.repo.owner,
36+
repo: context.repo.repo,
37+
title: title,
38+
body: body,
39+
labels: labels
40+
});

package-lock.json

Lines changed: 41 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/report-issue/route.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
3+
export async function POST(request: NextRequest) {
4+
try {
5+
const body = await request.json();
6+
const { type, description, userAgent } = body;
7+
8+
if (!type || !description) {
9+
return NextResponse.json(
10+
{ error: 'Type and description are required' },
11+
{ status: 400 }
12+
);
13+
}
14+
15+
const githubToken = process.env.GITHUB_PAT;
16+
const githubOwner = process.env.GITHUB_OWNER || 'victorhuangwq';
17+
const githubRepo = process.env.GITHUB_REPO || 'story-to-manga';
18+
19+
if (!githubToken) {
20+
console.error('GitHub PAT not configured');
21+
return NextResponse.json(
22+
{ error: 'Issue reporting not configured' },
23+
{ status: 500 }
24+
);
25+
}
26+
27+
const response = await fetch(
28+
`https://api.github.com/repos/${githubOwner}/${githubRepo}/dispatches`,
29+
{
30+
method: 'POST',
31+
headers: {
32+
Accept: 'application/vnd.github.v3+json',
33+
Authorization: `Bearer ${githubToken}`,
34+
'Content-Type': 'application/json',
35+
},
36+
body: JSON.stringify({
37+
event_type: 'create-issue',
38+
client_payload: {
39+
type,
40+
description,
41+
user_agent: userAgent || 'Unknown',
42+
timestamp: new Date().toISOString(),
43+
},
44+
}),
45+
}
46+
);
47+
48+
if (!response.ok) {
49+
const errorText = await response.text();
50+
console.error('GitHub API error:', response.status, errorText);
51+
return NextResponse.json(
52+
{ error: 'Failed to submit issue' },
53+
{ status: response.status }
54+
);
55+
}
56+
57+
return NextResponse.json(
58+
{ success: true, message: 'Issue submitted successfully' },
59+
{ status: 200 }
60+
);
61+
} catch (error) {
62+
console.error('Error submitting issue:', error);
63+
return NextResponse.json(
64+
{ error: 'Internal server error' },
65+
{ status: 500 }
66+
);
67+
}
68+
}

src/app/page.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useCallback, useId, useRef } from "react";
3+
import { useCallback, useId, useRef, useState } from "react";
44
import AccordionSection from "@/components/AccordionSection";
55
import CharacterCard from "@/components/CharacterCard";
66
import CollapsibleSection from "@/components/CollapsibleSection";
@@ -9,6 +9,7 @@ import ImageUpload from "@/components/ImageUpload";
99
import PanelCard from "@/components/PanelCard";
1010
import RerunButton from "@/components/RerunButton";
1111
import ShareableComicLayout from "@/components/ShareableComicLayout";
12+
import ReportIssueModal from "@/components/ReportIssueModal";
1213
import { useAppInitialization } from "@/hooks/useAppInitialization";
1314
import { useAutoSave } from "@/hooks/useAutoSave";
1415
import { useModalEscape } from "@/hooks/useEscapeKey";
@@ -62,6 +63,9 @@ export default function Home() {
6263
const comicRadioId = useId();
6364
const storyTextareaId = useId();
6465
const analysisHeadingId = useId();
66+
67+
// State for report issue modal
68+
const [isReportModalOpen, setIsReportModalOpen] = useState(false);
6569
const charactersHeadingId = useId();
6670
const layoutHeadingId = useId();
6771
const panelsHeadingId = useId();
@@ -1147,10 +1151,9 @@ export default function Home() {
11471151
</div>
11481152

11491153
{/* Floating Report Issue Button */}
1150-
<a
1151-
href="https://github.com/victorhuangwq/story-to-manga/issues/new"
1152-
target="_blank"
1153-
rel="noopener noreferrer"
1154+
<button
1155+
type="button"
1156+
onClick={() => setIsReportModalOpen(true)}
11541157
className="floating-report-btn"
11551158
title="Report an issue"
11561159
>
@@ -1159,7 +1162,13 @@ export default function Home() {
11591162
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15h2v-6h-2v6zm0-8h2V7h-2v2z" />
11601163
</svg>
11611164
Report Issue
1162-
</a>
1165+
</button>
1166+
1167+
{/* Report Issue Modal */}
1168+
<ReportIssueModal
1169+
isOpen={isReportModalOpen}
1170+
onClose={() => setIsReportModalOpen(false)}
1171+
/>
11631172

11641173
{/* Image Modal */}
11651174
{modalImage && (

0 commit comments

Comments
 (0)