mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
Add an overlay when hovering over apps, misc fixes (#108)
This commit is contained in:
parent
5be90e492f
commit
c55a0bdb68
@ -22,10 +22,15 @@
|
|||||||
transform 0.2s ease-in-out,
|
transform 0.2s ease-in-out,
|
||||||
box-shadow 0.2s ease-in-out;
|
box-shadow 0.2s ease-in-out;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
|
||||||
|
.hoverOverlay {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +100,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hoverOverlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hoverContent {
|
||||||
|
padding: 1rem;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hoverInfo {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.warningText {
|
||||||
|
color: #ffd700;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.grid {
|
.grid {
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
@ -5,6 +5,16 @@ import { type BuildAppResult, getRecentApps } from '~/lib/persistence/apps';
|
|||||||
import styles from './ExampleLibraryApps.module.scss';
|
import styles from './ExampleLibraryApps.module.scss';
|
||||||
import { importChat } from '~/lib/persistence/useChatHistory';
|
import { importChat } from '~/lib/persistence/useChatHistory';
|
||||||
|
|
||||||
|
const formatDate = (date: Date) => {
|
||||||
|
return new Intl.DateTimeFormat('en-US', {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
}).format(date);
|
||||||
|
};
|
||||||
|
|
||||||
export const ExampleLibraryApps = () => {
|
export const ExampleLibraryApps = () => {
|
||||||
const [numApps, setNumApps] = useState<number>(6);
|
const [numApps, setNumApps] = useState<number>(6);
|
||||||
const [apps, setApps] = useState<BuildAppResult[]>([]);
|
const [apps, setApps] = useState<BuildAppResult[]>([]);
|
||||||
@ -71,6 +81,17 @@ export const ExampleLibraryApps = () => {
|
|||||||
<div className={styles.placeholderImage}>{app.title || 'No preview'}</div>
|
<div className={styles.placeholderImage}>{app.title || 'No preview'}</div>
|
||||||
)}
|
)}
|
||||||
<div className={styles.appTitle}>{app.title || 'Untitled App'}</div>
|
<div className={styles.appTitle}>{app.title || 'Untitled App'}</div>
|
||||||
|
<div className={styles.hoverOverlay}>
|
||||||
|
<div className={styles.hoverContent}>
|
||||||
|
<div className={styles.hoverInfo}>
|
||||||
|
<div>
|
||||||
|
Created at {formatDate(new Date(app.createdAt))} in {Math.round(app.elapsedMinutes)} minutes
|
||||||
|
</div>
|
||||||
|
<div>{app.totalPeanuts} peanuts</div>
|
||||||
|
{app.outcome !== 'success' && <div className={styles.warningText}>⚠️ Not all tests are passing</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,6 +17,7 @@ export interface BuildAppResult {
|
|||||||
protocolChatId: string;
|
protocolChatId: string;
|
||||||
outcome: BuildAppOutcome;
|
outcome: BuildAppOutcome;
|
||||||
appId: string;
|
appId: string;
|
||||||
|
createdAt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function databaseRowToBuildAppResult(row: any): BuildAppResult {
|
function databaseRowToBuildAppResult(row: any): BuildAppResult {
|
||||||
@ -35,6 +36,7 @@ function databaseRowToBuildAppResult(row: any): BuildAppResult {
|
|||||||
protocolChatId: row.protocol_chat_id,
|
protocolChatId: row.protocol_chat_id,
|
||||||
outcome,
|
outcome,
|
||||||
appId: row.app_id,
|
appId: row.app_id,
|
||||||
|
createdAt: row.created_at,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,10 @@ export interface ResumeChatInfo {
|
|||||||
|
|
||||||
export async function importChat(title: string, messages: Message[]) {
|
export async function importChat(title: string, messages: Message[]) {
|
||||||
try {
|
try {
|
||||||
const chat = await database.createChat(title, messages);
|
// Remove any peanuts when importing another chat, these are just for the current user.
|
||||||
|
const newMessages = messages.map((msg) => ({ ...msg, peanuts: undefined }));
|
||||||
|
|
||||||
|
const chat = await database.createChat(title, newMessages);
|
||||||
window.location.href = `/chat/${chat.id}`;
|
window.location.href = `/chat/${chat.id}`;
|
||||||
toast.success('Chat imported successfully');
|
toast.success('Chat imported successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user