Skip to content

Commit a4e3d11

Browse files
committed
fix: moved from toast to dialogs
1 parent 47aa338 commit a4e3d11

File tree

10 files changed

+280
-179
lines changed

10 files changed

+280
-179
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ node_modules
1111
dist
1212
dist-ssr
1313
*.local
14+
allcode.txt
1415

1516
# Editor directories and files
1617
.vscode/*

allcode.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
# Directories to exclude (won't be recursed into) - comparison done case-insensitively.
5+
EXCLUDE_DIRS = {"node_modules", ".git"}
6+
7+
# Files to exclude (by exact name, case-insensitive)
8+
EXCLUDE_FILES = {
9+
".gitignore",
10+
"package.json",
11+
"tsconfig.json",
12+
"tailwind.config.js",
13+
"tailwind.config.ts",
14+
"vite.config.js",
15+
"vite.config.ts",
16+
".prettierrc",
17+
".prettierrc.json",
18+
".prettierrc.js",
19+
"package-lock.json",
20+
"allcode.py",
21+
"readme.md",
22+
"allcode.txt", # Exclude the output file
23+
}
24+
25+
26+
def is_excluded_file(filename):
27+
"""
28+
Check if a file should be excluded.
29+
- Matches the exclusion list (case-insensitive)
30+
- Ignores any file whose name contains 'config' (case-insensitive)
31+
"""
32+
lower_name = filename.lower()
33+
if lower_name in EXCLUDE_FILES:
34+
return True
35+
if "config" in lower_name:
36+
return True
37+
return False
38+
39+
40+
def main():
41+
output_filename = "allcode.txt"
42+
with open(output_filename, "w", encoding="utf-8") as outfile:
43+
# Walk the project starting at the current directory ('.')
44+
for root, dirs, files in os.walk("."):
45+
# Exclude specified directories (case-insensitive)
46+
dirs[:] = [d for d in dirs if d.lower() not in EXCLUDE_DIRS]
47+
48+
for file in files:
49+
if is_excluded_file(file):
50+
continue # Skip excluded files
51+
52+
full_path = os.path.join(root, file)
53+
# Get the relative path with forward slashes for consistency
54+
relative_path = os.path.relpath(full_path, ".").replace(os.sep, "/")
55+
56+
# Write the file header.
57+
outfile.write(f"{relative_path}:\n")
58+
59+
try:
60+
with open(full_path, "r", encoding="utf-8") as f:
61+
# Check if this is a JSON file inside a 'data' folder.
62+
path_parts = os.path.normpath(relative_path).split(os.sep)
63+
is_data_json = file.lower().endswith(".json") and any(
64+
part.lower() == "data" for part in path_parts[:-1]
65+
)
66+
67+
if is_data_json:
68+
# Read only the first 10 lines.
69+
lines = []
70+
for i in range(10):
71+
line = f.readline()
72+
if not line:
73+
break
74+
lines.append(line.rstrip("\n"))
75+
content = "\n".join(lines)
76+
# If there's more content, append an ellipsis.
77+
if f.readline():
78+
content += "\n..."
79+
else:
80+
content = f.read()
81+
except UnicodeDecodeError:
82+
content = "[Error reading file: binary or non-UTF-8 content]"
83+
except Exception as e:
84+
content = f"[Error reading file: {e}]"
85+
86+
# Indent each line of the content by 4 spaces.
87+
indented_content = "\n".join(
88+
" " + line for line in content.splitlines()
89+
)
90+
outfile.write(indented_content + "\n\n")
91+
92+
print(f"All code has been collected into '{output_filename}'.")
93+
94+
95+
if __name__ == "__main__":
96+
main()

src/App.tsx

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,23 @@
1-
"use client"
1+
'use client';
22

3-
import { useState } from "react"
4-
import StatementBuilder from "./components/StatementBuilder"
5-
import StatementWizard from "./components/StatementWizard"
6-
import type { Statement } from "../types/types"
7-
import { Eye, EyeOff } from "lucide-react"
8-
import { PreStatement } from "../types/types"
3+
import StatementBuilder from './components/StatementBuilder';
4+
import StatementWizard from './components/StatementWizard';
95

10-
// For testing purposes, we'll hardcode a username here
11-
// In a real application, this would come from a route parameter or user session
12-
const USERNAME = "Eve"
6+
const USERNAME = 'Eve';
137

148
export default function Home() {
15-
const [statements, setStatements] = useState<Statement[]>([])
16-
17-
const handleAddStatement = (newStatement: PreStatement) => {
18-
const fullStatement: Statement = {
19-
...newStatement,
20-
id: Date.now().toString(), // Generate an id (consider using a better id generator for production)
21-
};
22-
setStatements((prev) => [...prev, fullStatement]);
23-
};
24-
259
return (
26-
<main className="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 py-12">
27-
<div className="container mx-auto px-4 max-w-6xl">
28-
<h1 className="text-3xl font-bold mb-8 text-center">Statement Builders for {USERNAME}</h1>
29-
<div className="grid md:grid-cols-2 gap-8">
30-
<div className="bg-white rounded-xl shadow-lg p-6">
31-
<h2 className="text-2xl font-bold mb-4">Original Statement Builder</h2>
32-
<StatementBuilder onAddStatement={handleAddStatement} username={USERNAME} />
33-
</div>
34-
<div className="bg-white rounded-xl shadow-lg p-6">
35-
<h2 className="text-2xl font-bold mb-4">New Statement Wizard</h2>
36-
<StatementWizard onComplete={handleAddStatement} username={USERNAME} />
37-
</div>
38-
</div>
10+
<main className='min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 py-12'>
11+
<div className='container mx-auto px-4 max-w-3xl'>
12+
<h1 className='text-3xl font-bold mb-8 text-center'>
13+
Statement Builders for {USERNAME}
14+
</h1>
3915

40-
{statements.length > 0 && (
41-
<div className="mt-12 bg-white rounded-xl shadow-lg p-6">
42-
<h2 className="text-2xl font-bold mb-4">Created Statements</h2>
43-
<div className="space-y-3">
44-
{statements.map((statement) => (
45-
<div
46-
key={statement.id}
47-
className="p-4 rounded-lg bg-gray-50 flex items-center justify-between group hover:bg-gray-100 transition-colors"
48-
>
49-
<div className="flex-1">
50-
<span className="font-medium text-blue-600">{statement.subject}</span>{" "}
51-
<span className="font-medium text-green-600">{statement.verb}</span>{" "}
52-
<span className="font-medium text-yellow-600">{statement.object}</span>
53-
</div>
54-
<div className="text-gray-400 group-hover:text-gray-600">
55-
{statement.isPublic ? <Eye className="w-4 h-4" /> : <EyeOff className="w-4 h-4" />}
56-
</div>
57-
</div>
58-
))}
59-
</div>
60-
</div>
61-
)}
16+
<div className='bg-white rounded-xl shadow-lg p-6 '>
17+
<StatementWizard onComplete={() => {}} username={USERNAME} />
18+
<StatementBuilder onAddStatement={() => {}} username={USERNAME} />
19+
</div>
6220
</div>
6321
</main>
64-
)
22+
);
6523
}
66-

src/assets/react.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/StatementBuilder.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
4747
const [editingStatementId, setEditingStatementId] = useState<string | null>(
4848
null
4949
);
50+
const [duplicateConfirmation, setDuplicateConfirmation] = useState<{
51+
isOpen: boolean;
52+
statement: Statement | null;
53+
}>({ isOpen: false, statement: null });
54+
5055
const [editingPart, setEditingPart] = useState<
5156
'subject' | 'verb' | 'object' | null
5257
>(null);
@@ -79,6 +84,8 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
7984
setEditingPart(null);
8085
};
8186

87+
// Duplicate check: subject, verb, object (and later adverbial if needed)
88+
// Note: public/private is not considered.
8289
const isStatementUnique = (
8390
newStatement: Omit<Statement, 'id'>,
8491
excludeId?: string
@@ -89,6 +96,8 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
8996
existingStatement.subject === newStatement.subject &&
9097
existingStatement.verb === newStatement.verb &&
9198
existingStatement.object === newStatement.object
99+
// Future: To add adverbial comparison, uncomment below:
100+
// && existingStatement.adverbial === newStatement.adverbial
92101
);
93102
};
94103

@@ -105,20 +114,30 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
105114

106115
if (isStatementUnique(newStatement)) {
107116
setStatements((prevStatements) => [...prevStatements, newStatement]);
108-
onAddStatement(newStatement); // Add this line to update the shared list
117+
onAddStatement(newStatement);
109118
console.log('Statement:', newStatement);
110-
toast.success('Statement created successfully!');
111119
// Reset form fields
112-
setSubject('Eve');
120+
setSubject(username);
113121
setVerb(null);
114122
setObject('');
115123
setIsPublic(false);
116124
} else {
117-
toast.error('This statement already exists!');
125+
// Open the duplicate confirmation dialog.
126+
setDuplicateConfirmation({ isOpen: true, statement: newStatement });
127+
console.error('Duplicate statement detected:', newStatement);
118128
}
119129
}
120130
};
121131

132+
const handleDuplicateCancel = () => {
133+
setDuplicateConfirmation({ isOpen: false, statement: null });
134+
};
135+
136+
const handleDuplicateConfirm = () => {
137+
// Just dismiss the dialog—do not add the duplicate.
138+
setDuplicateConfirmation({ isOpen: false, statement: null });
139+
};
140+
122141
const handleAddDescriptor = async (newDescriptor: string) => {
123142
const updatedSubjects = subjects.map((subject) => {
124143
if (subject.subject === username) {
@@ -350,7 +369,7 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
350369
}, [username]);
351370

352371
return (
353-
<div className='bg-white rounded-xl shadow-lg p-6 w-full max-w-2xl'>
372+
<div className='bg-white rounded-xl shadow-lg p-6 w-full'>
354373
<h1 className='text-2xl font-bold mb-4'>Statement Builder</h1>
355374
<form onSubmit={handleSubmit} className='space-y-4'>
356375
<div>
@@ -475,6 +494,14 @@ const StatementBuilder: React.FC<StatementBuilderProps> = ({
475494
title='Delete Statement'
476495
description='Are you sure you want to delete this statement? This action cannot be undone.'
477496
/>
497+
<ConfirmationDialog
498+
isOpen={duplicateConfirmation.isOpen}
499+
onClose={handleDuplicateCancel}
500+
onConfirm={handleDuplicateConfirm}
501+
title='Duplicate Statement'
502+
description='This statement already exists and will not be added.'
503+
singleButton
504+
/>
478505
</div>
479506
);
480507
};

src/components/StatementWizard.tsx

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

33
import { useState, useMemo } from 'react';
4-
import { Dialog, DialogContent, DialogTitle, DialogDescription } from './ui/dialog';
4+
import {
5+
Dialog,
6+
DialogContent,
7+
DialogTitle,
8+
DialogDescription,
9+
} from './ui/dialog';
510
import { Button } from './ui/button';
611
import { Input } from './ui/input';
712
import { Plus, ArrowLeft, Eye, EyeOff } from 'lucide-react';
@@ -329,15 +334,15 @@ const StatementWizard: React.FC<StatementWizardProps> = ({
329334
<>
330335
<Button onClick={handleOpen} className='w-full'>
331336
<Plus className='w-5 h-5 mr-2' />
332-
Add New Statement
337+
Statement Wizzard
333338
</Button>
334339

335340
<Dialog open={isOpen} onOpenChange={handleClose}>
336341
<DialogContent className='sm:max-w-[600px] pt-6'>
337-
<DialogDescription className="sr-only">
338-
Confirmation Dialog
339-
</DialogDescription>
340-
<DialogTitle className="sr-only">Confirmation Dialog</DialogTitle>
342+
<DialogDescription className='sr-only'>
343+
Confirmation Dialog
344+
</DialogDescription>
345+
<DialogTitle className='sr-only'>Confirmation Dialog</DialogTitle>
341346
<div className='relative'>
342347
{step !== 'who' && (
343348
<Button

src/components/ui/command.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ Command.displayName = CommandPrimitive.displayName;
2727
const CommandDialog = ({ children, ...props }: DialogProps) => {
2828
return (
2929
<Dialog {...props}>
30-
<DialogTitle className="sr-only">Command</DialogTitle>
31-
<DialogDescription className="sr-only">
32-
Command
33-
</DialogDescription>
30+
<DialogTitle className='sr-only'>Command</DialogTitle>
31+
<DialogDescription className='sr-only'>Command</DialogDescription>
3432
<DialogContent className='overflow-hidden p-0 shadow-lg'>
3533
<Command className='[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5'>
3634
{children}
@@ -120,13 +118,12 @@ const CommandItem = React.forwardRef<
120118
<CommandPrimitive.Item
121119
ref={ref}
122120
className={cn(
123-
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
121+
'relative flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
124122
className
125123
)}
126124
{...props}
127125
/>
128126
));
129-
130127
CommandItem.displayName = CommandPrimitive.Item.displayName;
131128

132129
const CommandShortcut = ({

0 commit comments

Comments
 (0)