mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-24 11:14:23 +01:00
ignore
This commit is contained in:
461
theme-test.java
461
theme-test.java
@@ -1,461 +0,0 @@
|
||||
package com.example.theme;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
import java.time.*;
|
||||
import java.time.format.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.sql.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
// Enum definition
|
||||
public enum LogLevel {
|
||||
DEBUG(0, "Debug"),
|
||||
INFO(1, "Info"),
|
||||
WARN(2, "Warning"),
|
||||
ERROR(3, "Error");
|
||||
|
||||
private final int level;
|
||||
private final String description;
|
||||
|
||||
LogLevel(int level, String description) {
|
||||
this.level = level;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getLevel() { return level; }
|
||||
public String getDescription() { return description; }
|
||||
}
|
||||
|
||||
// Interface with generics
|
||||
public interface Repository<T extends Entity> {
|
||||
Optional<T> findById(Long id);
|
||||
List<T> findAll();
|
||||
T save(T entity);
|
||||
void delete(Long id);
|
||||
Stream<T> stream();
|
||||
|
||||
@FunctionalInterface
|
||||
interface Predicate<T> {
|
||||
boolean test(T t);
|
||||
}
|
||||
}
|
||||
|
||||
// Abstract class
|
||||
public abstract class AbstractService<T extends Entity> implements Repository<T> {
|
||||
protected final Map<Long, T> cache = new ConcurrentHashMap<>();
|
||||
protected volatile boolean initialized = false;
|
||||
|
||||
@Override
|
||||
public Optional<T> findById(Long id) {
|
||||
return Optional.ofNullable(cache.get(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> findAll() {
|
||||
return new ArrayList<>(cache.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return cache.values().stream();
|
||||
}
|
||||
|
||||
protected abstract void validate(T entity) throws ValidationException;
|
||||
}
|
||||
|
||||
// Annotation definition
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface Service {
|
||||
String value() default "";
|
||||
boolean transactional() default true;
|
||||
Class<?>[] exceptions() = {};
|
||||
}
|
||||
|
||||
// Record class (Java 14+)
|
||||
public record User(
|
||||
Long id,
|
||||
String username,
|
||||
String email,
|
||||
@Deprecated String fullName,
|
||||
LocalDateTime createdAt,
|
||||
boolean active
|
||||
) implements Entity {
|
||||
|
||||
public User {
|
||||
Objects.requireNonNull(username, "Username cannot be null");
|
||||
Objects.requireNonNull(email, "Email cannot be null");
|
||||
Objects.requireNonNull(createdAt, "Created date cannot be null");
|
||||
}
|
||||
|
||||
public static User of(String username, String email) {
|
||||
return new User(null, username, email, null, LocalDateTime.now(), true);
|
||||
}
|
||||
|
||||
public User withId(Long id) {
|
||||
return new User(id, username, email, fullName, createdAt, active);
|
||||
}
|
||||
}
|
||||
|
||||
// Exception classes
|
||||
public class ValidationException extends RuntimeException {
|
||||
private final List<String> errors;
|
||||
|
||||
public ValidationException(String message) {
|
||||
super(message);
|
||||
this.errors = List.of(message);
|
||||
}
|
||||
|
||||
public ValidationException(List<String> errors) {
|
||||
super(String.join(", ", errors));
|
||||
this.errors = Collections.unmodifiableList(errors);
|
||||
}
|
||||
|
||||
public List<String> getErrors() { return errors; }
|
||||
}
|
||||
|
||||
public class ResourceNotFoundException extends RuntimeException {
|
||||
public ResourceNotFoundException(String resource, Long id) {
|
||||
super(String.format("%s with id %d not found", resource, id));
|
||||
}
|
||||
}
|
||||
|
||||
// Service implementation
|
||||
@Service(value = "userService", transactional = true)
|
||||
public class UserService extends AbstractService<User> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
||||
private static final int MAX_RETRY_ATTEMPTS = 3;
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(30);
|
||||
|
||||
private final EmailService emailService;
|
||||
private final UserRepository userRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Inject
|
||||
public UserService(EmailService emailService,
|
||||
UserRepository userRepository,
|
||||
PasswordEncoder passwordEncoder) {
|
||||
this.emailService = emailService;
|
||||
this.userRepository = userRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validate(User user) throws ValidationException {
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
if (user.username() == null || user.username().trim().isEmpty()) {
|
||||
errors.add("Username is required");
|
||||
} else if (!user.username().matches("^[a-zA-Z0-9_]{3,20}$")) {
|
||||
errors.add("Username must be 3-20 characters, alphanumeric and underscore only");
|
||||
}
|
||||
|
||||
if (user.email() == null || !user.email().matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
|
||||
errors.add("Valid email is required");
|
||||
}
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
throw new ValidationException(errors);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public User createUser(CreateUserRequest request) throws ValidationException {
|
||||
logger.info("Creating new user: {}", request.username());
|
||||
|
||||
// Check if user already exists
|
||||
if (userRepository.findByUsername(request.username()).isPresent()) {
|
||||
throw new ValidationException("Username already exists");
|
||||
}
|
||||
|
||||
if (userRepository.findByEmail(request.email()).isPresent()) {
|
||||
throw new ValidationException("Email already exists");
|
||||
}
|
||||
|
||||
// Create new user
|
||||
User user = User.of(request.username(), request.email())
|
||||
.withId(generateId());
|
||||
|
||||
validate(user);
|
||||
|
||||
try {
|
||||
User savedUser = userRepository.save(user);
|
||||
cache.put(savedUser.id(), savedUser);
|
||||
|
||||
// Send welcome email asynchronously
|
||||
CompletableFuture.runAsync(() ->
|
||||
emailService.sendWelcomeEmail(savedUser)
|
||||
).exceptionally(throwable -> {
|
||||
logger.error("Failed to send welcome email to user {}", savedUser.id(), throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
logger.info("Successfully created user with ID: {}", savedUser.id());
|
||||
return savedUser;
|
||||
|
||||
} catch (DataAccessException e) {
|
||||
logger.error("Database error while creating user", e);
|
||||
throw new ServiceException("Failed to create user", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<User> findByUsername(String username) {
|
||||
return cache.values().stream()
|
||||
.filter(user -> user.username().equals(username))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
public List<User> findActiveUsers() {
|
||||
return cache.values().stream()
|
||||
.filter(User::active)
|
||||
.sorted(Comparator.comparing(User::createdAt).reversed())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Retry(maxAttempts = MAX_RETRY_ATTEMPTS, backoff = @Backoff(delay = 1000))
|
||||
public User updateUser(Long id, UpdateUserRequest request) {
|
||||
User existingUser = findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("User", id));
|
||||
|
||||
User updatedUser = new User(
|
||||
id,
|
||||
request.username() != null ? request.username() : existingUser.username(),
|
||||
request.email() != null ? request.email() : existingUser.email(),
|
||||
existingUser.fullName(),
|
||||
existingUser.createdAt(),
|
||||
request.active() != null ? request.active() : existingUser.active()
|
||||
);
|
||||
|
||||
validate(updatedUser);
|
||||
|
||||
try {
|
||||
User savedUser = userRepository.save(updatedUser);
|
||||
cache.put(id, savedUser);
|
||||
return savedUser;
|
||||
} catch (DataAccessException e) {
|
||||
logger.error("Failed to update user with ID: {}", id, e);
|
||||
throw new ServiceException("Failed to update user", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
public CompletableFuture<Void> deleteUser(Long id) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
userRepository.deleteById(id);
|
||||
cache.remove(id);
|
||||
logger.info("Successfully deleted user with ID: {}", id);
|
||||
} catch (DataAccessException e) {
|
||||
logger.error("Failed to delete user with ID: {}", id, e);
|
||||
throw new ServiceException("Failed to delete user", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Long generateId() {
|
||||
return System.currentTimeMillis() + (long)(Math.random() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility class
|
||||
public final class DateUtils {
|
||||
|
||||
private DateUtils() {
|
||||
// Utility class - prevent instantiation
|
||||
}
|
||||
|
||||
private static final DateTimeFormatter ISO_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
|
||||
|
||||
public static String formatIsoDateTime(LocalDateTime dateTime) {
|
||||
return dateTime.atZone(ZoneId.systemDefault()).format(ISO_FORMATTER);
|
||||
}
|
||||
|
||||
public static LocalDateTime parseIsoDateTime(String isoString) {
|
||||
return LocalDateTime.parse(isoString, ISO_FORMATTER);
|
||||
}
|
||||
|
||||
public static boolean isWithinLastDays(LocalDateTime dateTime, int days) {
|
||||
return dateTime.isAfter(LocalDateTime.now().minusDays(days));
|
||||
}
|
||||
}
|
||||
|
||||
// Builder pattern
|
||||
public class UserQueryBuilder {
|
||||
private String username;
|
||||
private String email;
|
||||
private Boolean active;
|
||||
private LocalDateTime createdAfter;
|
||||
private LocalDateTime createdBefore;
|
||||
private SortOrder sortOrder = SortOrder.ASC;
|
||||
private String sortBy = "createdAt";
|
||||
private int limit = 100;
|
||||
private int offset = 0;
|
||||
|
||||
public UserQueryBuilder withUsername(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder withEmail(String email) {
|
||||
this.email = email;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder activeOnly(boolean active) {
|
||||
this.active = active;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder createdAfter(LocalDateTime date) {
|
||||
this.createdAfter = date;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder createdBefore(LocalDateTime date) {
|
||||
this.createdBefore = date;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder sortBy(String field, SortOrder order) {
|
||||
this.sortBy = field;
|
||||
this.sortOrder = order;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder limit(int limit) {
|
||||
this.limit = Math.max(1, Math.min(limit, 1000));
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQueryBuilder offset(int offset) {
|
||||
this.offset = Math.max(0, offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserQuery build() {
|
||||
return new UserQuery(username, email, active, createdAfter, createdBefore,
|
||||
sortBy, sortOrder, limit, offset);
|
||||
}
|
||||
}
|
||||
|
||||
// Lambda expressions and streams
|
||||
public class StreamProcessor {
|
||||
|
||||
private static final Map<String, Function<String, Object>> TYPE_CONVERTERS = Map.of(
|
||||
"string", s -> s,
|
||||
"int", Integer::parseInt,
|
||||
"double", Double::parseDouble,
|
||||
"boolean", Boolean::parseBoolean,
|
||||
"bigdecimal", BigDecimal::new,
|
||||
"bigint", BigInteger::new
|
||||
);
|
||||
|
||||
public Map<String, Object> processConfig(Properties properties) {
|
||||
return properties.entrySet().stream()
|
||||
.filter(entry -> entry.getKey() instanceof String)
|
||||
.filter(entry -> entry.getValue() != null)
|
||||
.collect(Collectors.toMap(
|
||||
entry -> (String) entry.getKey(),
|
||||
entry -> convertValue((String) entry.getKey(), (String) entry.getValue())
|
||||
));
|
||||
}
|
||||
|
||||
private Object convertValue(String key, String value) {
|
||||
String type = determineType(key, value);
|
||||
return TYPE_CONVERTERS.getOrDefault(type, Function.identity()).apply(value);
|
||||
}
|
||||
|
||||
private String determineType(String key, String value) {
|
||||
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
|
||||
return "boolean";
|
||||
} else if (value.matches("-?\\d+")) {
|
||||
return "int";
|
||||
} else if (value.matches("-?\\d*\\.\\d+")) {
|
||||
return "double";
|
||||
} else if (key.toLowerCase().contains("amount") || key.toLowerCase().contains("price")) {
|
||||
return "bigdecimal";
|
||||
}
|
||||
return "string";
|
||||
}
|
||||
|
||||
public List<String> validateEmails(List<String> emails) {
|
||||
return emails.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::trim)
|
||||
.filter(email -> !email.isEmpty())
|
||||
.filter(email -> email.matches("^[A-Za-z0-9+_.-]+@(.+)$"))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public CompletableFuture<List<User>> processUsersAsync(List<User> users) {
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
users.parallelStream()
|
||||
.filter(User::active)
|
||||
.filter(user -> user.createdAt().isAfter(LocalDateTime.now().minusYears(1)))
|
||||
.sorted(Comparator.comparing(User::username))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Main class for testing
|
||||
public class Main {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Main.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// Initialize application context
|
||||
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
|
||||
|
||||
// Get service bean
|
||||
UserService userService = context.getBean(UserService.class);
|
||||
|
||||
// Create test users
|
||||
List<User> users = Arrays.asList(
|
||||
User.of("john_doe", "john@example.com"),
|
||||
User.of("jane_smith", "jane@example.com"),
|
||||
User.of("bob_wilson", "bob@example.com")
|
||||
);
|
||||
|
||||
// Process users
|
||||
List<CompletableFuture<User>> futures = users.stream()
|
||||
.map(user -> {
|
||||
try {
|
||||
return CompletableFuture.completedFuture(userService.createUser(
|
||||
new CreateUserRequest(user.username(), user.email())
|
||||
));
|
||||
} catch (ValidationException e) {
|
||||
logger.error("Failed to create user: {}", user.username(), e);
|
||||
return CompletableFuture.<User>failedFuture(e);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Wait for all to complete
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.thenRun(() -> {
|
||||
logger.info("All users created successfully");
|
||||
System.out.println("Application started successfully!");
|
||||
})
|
||||
.exceptionally(throwable -> {
|
||||
logger.error("Failed to initialize users", throwable);
|
||||
System.err.println("Application startup failed!");
|
||||
return null;
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Application startup failed", e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
669
theme-test.md
669
theme-test.md
@@ -1,669 +0,0 @@
|
||||
# TextMate Grammar Token Examples
|
||||
|
||||
This file contains examples of every major TextMate token style for theme testing.
|
||||
|
||||
## Comments
|
||||
|
||||
<!-- HTML comment -->
|
||||
|
||||
// Single line comment
|
||||
/_ Multi-line comment _/
|
||||
|
||||
# Shell comment
|
||||
|
||||
/_ JSDoc comment with @param and @return _/
|
||||
|
||||
## Strings
|
||||
|
||||
"Double quoted string"
|
||||
'Single quoted string'
|
||||
`Backtick string`
|
||||
"String with \"escaped\" quotes"
|
||||
'String with \'escaped\' quotes'
|
||||
`String with \`escaped\` backticks`
|
||||
|
||||
## Template Literals
|
||||
|
||||
`Simple template literal`
|
||||
`Template with ${variable} interpolation`
|
||||
`Template with ${function.call()} expression`
|
||||
Multi-line template with ${nested.interpolation}
|
||||
|
||||
## Numbers
|
||||
|
||||
42
|
||||
-17
|
||||
3.14159
|
||||
-0.001
|
||||
1e10
|
||||
-2.5e-8
|
||||
0xFF
|
||||
0o755
|
||||
0b1010
|
||||
|
||||
## Keywords
|
||||
|
||||
if else elif for while do switch case default
|
||||
function class extends implements import export
|
||||
return break continue throw try catch finally
|
||||
var let const static async await yield
|
||||
new this super null undefined true false
|
||||
|
||||
## Storage Types
|
||||
|
||||
int float double string boolean char void
|
||||
static final abstract private public protected
|
||||
readonly volatile transient synchronized
|
||||
|
||||
## Constants
|
||||
|
||||
MAX_VALUE
|
||||
DEFAULT_TIMEOUT
|
||||
API_ENDPOINT
|
||||
PI
|
||||
E
|
||||
|
||||
## Variables
|
||||
|
||||
variableName
|
||||
\_privateVariable
|
||||
$specialVariable
|
||||
camelCase
|
||||
snake_case
|
||||
PascalCase
|
||||
kebab-case
|
||||
|
||||
## Functions
|
||||
|
||||
functionName()
|
||||
method.call()
|
||||
object.property()
|
||||
array[index]
|
||||
arrowFunction => expression
|
||||
|
||||
## Operators
|
||||
|
||||
- - - / % ++ --
|
||||
== === != !== > < >= <=
|
||||
&& || ! & | ^ ~ << >> >>>
|
||||
= += -= \*= /= %= &= |= ^= <<= >>= >>>=
|
||||
|
||||
## Punctuation
|
||||
|
||||
, ; : . ... ( ) [ ] { } < > / \\
|
||||
|
||||
# @ $ % ^ & \* - \_ + = | ~ ` ?
|
||||
|
||||
## Entities
|
||||
|
||||
ClassName
|
||||
InterfaceName
|
||||
EnumName
|
||||
TypeName
|
||||
MethodName
|
||||
PropertyName
|
||||
|
||||
## Tags
|
||||
|
||||
<div>
|
||||
<span>
|
||||
<p>
|
||||
<a href="link">
|
||||
<img src="image.jpg" alt="description" />
|
||||
|
||||
## Attributes
|
||||
|
||||
class="container"
|
||||
id="main"
|
||||
data-value="123"
|
||||
disabled
|
||||
required
|
||||
readonly
|
||||
|
||||
## CSS Selectors & Properties
|
||||
|
||||
.container
|
||||
#header
|
||||
.button:hover
|
||||
input[type="text"]
|
||||
::before
|
||||
::after
|
||||
|
||||
color: #ffffff;
|
||||
background: linear-gradient(45deg, #ff0000, #00ff00);
|
||||
font-size: 16px;
|
||||
margin: 0 auto;
|
||||
padding: 10px 20px;
|
||||
|
||||
## Regular Expressions
|
||||
|
||||
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
||||
/\d{3}-\d{3}-\d{4}/g
|
||||
/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})/
|
||||
|
||||
## URLs & Paths
|
||||
|
||||
https://example.com/path/to/resource
|
||||
file:///Users/username/project
|
||||
./relative/path
|
||||
../parent/directory
|
||||
/home/user/documents
|
||||
|
||||
## JSON
|
||||
|
||||
{
|
||||
"name": "example",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"react": "^18.0.0",
|
||||
"typescript": "^4.9.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"test": "jest"
|
||||
}
|
||||
}
|
||||
|
||||
## XML/HTML
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1>Title</h1>
|
||||
<p>Paragraph text</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
## SQL
|
||||
|
||||
SELECT u.id, u.name, u.email, COUNT(o.id) as order_count
|
||||
FROM users u
|
||||
LEFT JOIN orders o ON u.id = o.user_id
|
||||
WHERE u.active = true
|
||||
AND o.created_at >= '2023-01-01'
|
||||
GROUP BY u.id, u.name, u.email
|
||||
HAVING COUNT(o.id) > 5
|
||||
ORDER BY order_count DESC
|
||||
LIMIT 10;
|
||||
|
||||
## GraphQL
|
||||
|
||||
query GetUserProfile($userId: ID!, $includePosts: Boolean!) {
|
||||
user(id: $userId) {
|
||||
id
|
||||
name
|
||||
email
|
||||
avatar
|
||||
createdAt
|
||||
posts @include(if: $includePosts) {
|
||||
id
|
||||
title
|
||||
content
|
||||
publishedAt
|
||||
comments(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
author
|
||||
content
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Shell/Bash
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Variables
|
||||
|
||||
PROJECT*DIR="/home/user/projects"
|
||||
BACKUP_DIR="$PROJECT_DIR/backups"
|
||||
TIMESTAMP=$(date +"%Y%m%d*%H%M%S")
|
||||
|
||||
# Functions
|
||||
|
||||
create*backup() {
|
||||
local source_dir=$1
|
||||
local backup_file="$BACKUP_DIR/backup*$TIMESTAMP.tar.gz"
|
||||
|
||||
echo "Creating backup of $source_dir..."
|
||||
tar -czf "$backup_file" "$source_dir"
|
||||
echo "Backup created: $backup_file"
|
||||
|
||||
}
|
||||
|
||||
# Conditional logic
|
||||
|
||||
if [ -d "$PROJECT_DIR" ]; then
|
||||
create_backup "$PROJECT_DIR"
|
||||
else
|
||||
echo "Project directory not found: $PROJECT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Python
|
||||
|
||||
import os
|
||||
import sys
|
||||
from typing import List, Dict, Optional
|
||||
import requests
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class User:
|
||||
id: int
|
||||
name: str
|
||||
email: Optional[str] = None
|
||||
active: bool = True
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.name.strip():
|
||||
raise ValueError("Name cannot be empty")
|
||||
|
||||
class UserService:
|
||||
def **init**(self, api_url: str):
|
||||
self.api_url = api_url
|
||||
self.session = requests.Session()
|
||||
|
||||
async def get_user(self, user_id: int) -> Optional[User]:
|
||||
"""Fetch user data from API."""
|
||||
try:
|
||||
response = await self.session.get(f"{self.api_url}/users/{user_id}")
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return User(**data)
|
||||
except requests.RequestException as e:
|
||||
print(f"Error fetching user {user_id}: {e}")
|
||||
return None
|
||||
|
||||
## Rust
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
pub email: Option<String>, #[serde(default)]
|
||||
pub active: bool,
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn new(id: u64, name: String, email: Option<String>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
name,
|
||||
email,
|
||||
active: true,
|
||||
created_at: chrono::Utc::now(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_name(&self) -> String {
|
||||
match &self.email {
|
||||
Some(email) => format!("{} <{}>", self.name, email),
|
||||
None => self.name.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct UserService {
|
||||
api_url: String,
|
||||
client: reqwest::Client,
|
||||
}
|
||||
|
||||
impl UserService {
|
||||
pub fn new(api_url: String) -> Self {
|
||||
Self {
|
||||
api_url,
|
||||
client: reqwest::Client::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_user(&self, user_id: u64) -> Result<User, Box<dyn std::error::Error>> {
|
||||
let url = format!("{}/users/{}", self.api_url, user_id);
|
||||
let response = self.client.get(&url).send().await?;
|
||||
let user: User = response.json().await?;
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
## Go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email \*string `json:"email,omitempty"`
|
||||
Active bool `json:"active"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
type UserService struct {
|
||||
re UserRepository
|
||||
}
|
||||
|
||||
func NewUserService(repo UserRepository) \*UserService {
|
||||
return &UserService{repo: repo}
|
||||
}
|
||||
|
||||
func (s *UserService) GetUser(ctx context.Context, id int64) (*User, error) {
|
||||
user, err := s.repo.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user %d: %w", id, err)
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (s *UserService) CreateUser(ctx context.Context, req *CreateUserRequest) (\*User, error) {
|
||||
user := &User{
|
||||
Name: req.Name,
|
||||
Email: req.Email,
|
||||
Active: true,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
if err := s.repo.Create(ctx, user); err != nil {
|
||||
return nil, fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
## YAML
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-app
|
||||
namespace: production
|
||||
labels:
|
||||
app: web-app
|
||||
version: v1.2.3
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-app
|
||||
tier: frontend
|
||||
spec:
|
||||
containers: - name: web-app
|
||||
image: nginx:1.21-alpine
|
||||
ports: - containerPort: 80
|
||||
protocol: TCP
|
||||
env: - name: NODE_ENV
|
||||
value: "production" - name: API_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: app-secrets
|
||||
key: api-url
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "500m"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 80
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 80
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
|
||||
## TOML
|
||||
|
||||
[project]
|
||||
name = "example-app"
|
||||
version = "1.0.0"
|
||||
description = "An example application"
|
||||
authors = ["John Doe <john@example.com>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
homepage = "https://example.com"
|
||||
repository = "https://github.com/johndoe/example-app"
|
||||
keywords = ["web", "api", "rust"]
|
||||
categories = ["web-programming"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
log = "0.4"
|
||||
env_logger = "0.10"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = "0.4"
|
||||
mockito = "1.0"
|
||||
|
||||
[[bin]]
|
||||
name = "server"
|
||||
path = "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "client"
|
||||
path = "src/client.rs"
|
||||
|
||||
## Dockerfile
|
||||
|
||||
FROM node:18-alpine AS base
|
||||
|
||||
# Install dependencies only when needed
|
||||
|
||||
FROM base AS deps
|
||||
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies based on the preferred package manager
|
||||
|
||||
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml\* ./
|
||||
RUN \
|
||||
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||
elif [ -f package-lock.json ]; then npm ci; \
|
||||
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
# Next.js collects completely anonymous telemetry data about general usage.
|
||||
|
||||
# Learn more here: https://nextjs.org/telemetry
|
||||
|
||||
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN \
|
||||
if [ -f yarn.lock ]; then yarn run build; \
|
||||
elif [ -f package-lock.json ]; then npm run build; \
|
||||
elif [ -f pnpm-lock.yaml ]; then pnpm run build; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
|
||||
# Uncomment the following line in case you want to disable telemetry during runtime.
|
||||
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Set the correct permission for prerender cache
|
||||
|
||||
RUN mkdir .next
|
||||
RUN chown nextjs:nodejs .next
|
||||
|
||||
# Automatically leverage output traces to reduce image size
|
||||
|
||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
# set hostname to localhost
|
||||
|
||||
ENV HOSTNAME "0.0.0.0"
|
||||
|
||||
# server.js is created by next build from the standalone output
|
||||
|
||||
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
|
||||
## Makefile
|
||||
|
||||
.PHONY: help build test clean install dev lint format
|
||||
|
||||
# Default target
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
# Variables
|
||||
|
||||
APP_NAME := myapp
|
||||
VERSION := $(shell git describe --tags --always --dirty)
|
||||
BUILD_DIR := ./build
|
||||
DIST_DIR := ./dist
|
||||
GO_FILES := $(shell find . -name '\*.go' -type f)
|
||||
|
||||
help: ## Show this help message
|
||||
@echo "Available targets:"
|
||||
@grep -E '^[a-zA-Z_-]+:._?## ._$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.\*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
install: ## Install dependencies
|
||||
go mod download
|
||||
npm install
|
||||
|
||||
build: ## Build the application
|
||||
@echo "Building $(APP_NAME) version $(VERSION)..."
|
||||
mkdir -p $(BUILD_DIR)
|
||||
go build -ldflags "-X main.version=$(VERSION)" -o $(BUILD_DIR)/$(APP_NAME) ./cmd/main.go
|
||||
|
||||
test: ## Run tests
|
||||
go test -v ./...
|
||||
npm test
|
||||
|
||||
lint: ## Run linters
|
||||
golangci-lint run
|
||||
npx eslint .
|
||||
|
||||
format: ## Format code
|
||||
go fmt ./...
|
||||
npx prettier --write .
|
||||
|
||||
dev: ## Run in development mode
|
||||
go run ./cmd/main.go --dev
|
||||
|
||||
clean: ## Clean build artifacts
|
||||
rm -rf $(BUILD_DIR)
|
||||
rm -rf $(DIST_DIR)
|
||||
go clean -cache
|
||||
|
||||
docker-build: ## Build Docker image
|
||||
docker build -t $(APP_NAME):$(VERSION) .
|
||||
docker tag $(APP_NAME):$(VERSION) $(APP_NAME):latest
|
||||
|
||||
docker-run: ## Run Docker container
|
||||
docker run -p 8080:8080 $(APP_NAME):latest
|
||||
|
||||
release: ## Create a new release
|
||||
@echo "Creating release $(VERSION)"
|
||||
git tag -a $(VERSION) -m "Release $(VERSION)"
|
||||
git push origin $(VERSION)
|
||||
goreleaser release --rm-dist
|
||||
|
||||
## Git Diff
|
||||
|
||||
diff --git a/src/components/UserProfile.tsx b/src/components/UserProfile.tsx
|
||||
index 1234567..abcdefg 100644
|
||||
--- a/src/components/UserProfile.tsx
|
||||
+++ b/src/components/UserProfile.tsx
|
||||
@@ -10,7 +10,7 @@ interface User {
|
||||
id: number
|
||||
name: string
|
||||
email?: string
|
||||
|
||||
- createdAt: Date
|
||||
|
||||
* readonly createdAt: Date
|
||||
active: boolean
|
||||
}
|
||||
|
||||
@@ -25,8 +25,12 @@ const UserProfile: FC<{ user: User }> = ({ user }) => {
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [formData, setFormData] = useState(user)
|
||||
|
||||
- const handleSubmit = async (e: React.FormEvent) => {
|
||||
- e.preventDefault()
|
||||
- // Handle form submission
|
||||
- }
|
||||
- return (
|
||||
|
||||
* <div className="user-card">
|
||||
|
||||
- <div className={`user-card ${user.active ? 'active' : 'inactive'}`}>
|
||||
<h3>{user.name}</h3>
|
||||
<p>{user.email}</p>
|
||||
</div>
|
||||
347
theme-test.tsx
347
theme-test.tsx
@@ -1,347 +0,0 @@
|
||||
import React, { useState, useEffect, useCallback, useMemo } from "react"
|
||||
import { ComponentType, FC, ReactNode, JSX } from "react"
|
||||
|
||||
// Interface definitions
|
||||
interface User {
|
||||
id: number
|
||||
name: string
|
||||
email?: string
|
||||
readonly createdAt: Date
|
||||
active: boolean
|
||||
}
|
||||
|
||||
type Theme = "light" | "dark" | "auto"
|
||||
type Status = "pending" | "loading" | "success" | "error"
|
||||
|
||||
// Generic function with constraints
|
||||
function createRepository<T extends { id: number }>(items: T[]): Repository<T> {
|
||||
return new Repository(items)
|
||||
}
|
||||
|
||||
// Class definition
|
||||
class Repository<T> {
|
||||
private items: T[]
|
||||
protected cache: Map<string, T>
|
||||
|
||||
constructor(items: T[] = []) {
|
||||
this.items = items
|
||||
this.cache = new Map()
|
||||
}
|
||||
|
||||
public find(id: number): T | undefined {
|
||||
const x = undefined
|
||||
type x = { foo: undefined }
|
||||
return this.items.find((item) => item.id === id)
|
||||
}
|
||||
|
||||
public async findAll(): Promise<T[]> {
|
||||
return this.items
|
||||
}
|
||||
|
||||
get count(): number {
|
||||
return this.items.length
|
||||
}
|
||||
}
|
||||
|
||||
// Enum definition
|
||||
enum LogLevel {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
WARN = 2,
|
||||
ERROR = 3,
|
||||
}
|
||||
|
||||
// Constants
|
||||
const API_URL = "https://api.example.com"
|
||||
const MAX_RETRIES = 3
|
||||
const DEFAULT_TIMEOUT = 5000
|
||||
|
||||
// Regular expressions
|
||||
const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
||||
const PHONE_REGEX = /^\+?1?-?\.?\s?\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})$/
|
||||
|
||||
// Template literals
|
||||
const greeting = `Hello, ${user.name}!`
|
||||
const sql = `
|
||||
SELECT * FROM users
|
||||
WHERE active = true
|
||||
AND created_at > '${new Date().toISOString()}'
|
||||
`
|
||||
|
||||
// String source examples (CSS-in-JS, GraphQL, etc.)
|
||||
const styledComponent = css`
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const graphqlQuery = `
|
||||
query GetUserProfile($userId: ID!) {
|
||||
user(id: $userId) {
|
||||
id
|
||||
name
|
||||
email
|
||||
avatar
|
||||
createdAt
|
||||
posts {
|
||||
id
|
||||
title
|
||||
content
|
||||
publishedAt
|
||||
comments {
|
||||
id
|
||||
author
|
||||
content
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const htmlTemplate = `
|
||||
<div class="user-card">
|
||||
<img src="${user.avatar}" alt="${user.name}" class="avatar" />
|
||||
<div class="user-info">
|
||||
<h3>${user.name}</h3>
|
||||
<p>${user.email}</p>
|
||||
<span class="status ${user.active ? "active" : "inactive"}">
|
||||
${user.active ? "Active" : "Inactive"}
|
||||
</span>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button onclick="editUser(${user.id})">Edit</button>
|
||||
<button onclick="deleteUser(${user.id})" class="danger">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
|
||||
// Arrow functions
|
||||
const debounce = <T extends (...args: any[]) => any>(func: T, wait: number): ((...args: Parameters<T>) => void) => {
|
||||
let timeout: NodeJS.Timeout
|
||||
return (...args: Parameters<T>) => {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => func(...args), wait)
|
||||
}
|
||||
}
|
||||
|
||||
// Async function
|
||||
async function fetchUserData(userId: number): Promise<User> {
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/users/${userId}`)
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch user data:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// React component with various patterns
|
||||
const ThemeProvider: FC<{ children: ReactNode; theme?: Theme }> = ({ children, theme = "auto" }) => {
|
||||
const [currentTheme, setCurrentTheme] = useState<Theme>(theme)
|
||||
const [status, setStatus] = useState<Status>("pending")
|
||||
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
const handleChange = (e: MediaQueryListEvent) => {
|
||||
setCurrentTheme(e.matches ? "dark" : "light")
|
||||
}
|
||||
|
||||
mediaQuery.addEventListener("change", handleChange)
|
||||
return () => mediaQuery.removeEventListener("change", handleChange)
|
||||
}, [])
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
theme: currentTheme,
|
||||
setTheme: setCurrentTheme,
|
||||
toggleTheme: () => setCurrentTheme((prev) => (prev === "light" ? "dark" : "light")),
|
||||
}),
|
||||
[currentTheme],
|
||||
)
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={contextValue}>
|
||||
<div className={`theme-${currentTheme}`} data-theme={currentTheme}>
|
||||
{children}
|
||||
</div>
|
||||
</ThemeContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
// Higher-order component
|
||||
function withLogging<P extends object>(Component: ComponentType<P>): ComponentType<P> {
|
||||
return function LoggedComponent(props: P) {
|
||||
console.log("Rendering component:", Component.name)
|
||||
return <Component {...props} />
|
||||
}
|
||||
}
|
||||
|
||||
// Custom hook
|
||||
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void] {
|
||||
const [storedValue, setStoredValue] = useState<T>(() => {
|
||||
try {
|
||||
const item = window.localStorage.getItem(key)
|
||||
return item ? JSON.parse(item) : initialValue
|
||||
} catch (error) {
|
||||
console.warn(`Error reading localStorage key "${key}":`, error)
|
||||
return initialValue
|
||||
}
|
||||
})
|
||||
|
||||
const setValue = useCallback(
|
||||
(value: T) => {
|
||||
try {
|
||||
setStoredValue(value)
|
||||
window.localStorage.setItem(key, JSON.stringify(value))
|
||||
} catch (error) {
|
||||
console.warn(`Error setting localStorage key "${key}":`, error)
|
||||
}
|
||||
},
|
||||
[key],
|
||||
)
|
||||
|
||||
return [storedValue, setValue]
|
||||
}
|
||||
|
||||
// JSX component with various elements
|
||||
const UserProfile: FC<{ user: User; onUpdate?: (user: User) => void }> = ({ user, onUpdate }) => {
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [formData, setFormData] = useState(user)
|
||||
const [errors, setErrors] = useState<Record<string, string>>({})
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
// Validation
|
||||
if (!formData.name.trim()) {
|
||||
setErrors({ name: "Name is required" })
|
||||
return
|
||||
}
|
||||
|
||||
if (formData.email && !EMAIL_REGEX.test(formData.email)) {
|
||||
setErrors({ email: "Invalid email format" })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
setStatus("loading")
|
||||
await onUpdate?.(formData)
|
||||
setStatus("success")
|
||||
setIsEditing(false)
|
||||
} catch (error) {
|
||||
setStatus("error")
|
||||
setErrors({ submit: "Failed to update profile" })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="user-profile">
|
||||
<div className="user-header">
|
||||
<h2>{user.name}</h2>
|
||||
<span className={`status status-${user.active ? "active" : "inactive"}`}>
|
||||
{user.active ? "Active" : "Inactive"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{isEditing ? (
|
||||
<form onSubmit={handleSubmit} className="user-form">
|
||||
<div className="form-group">
|
||||
<label htmlFor="name">Name:</label>
|
||||
<input
|
||||
id="name"
|
||||
type="text"
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
className={errors.name ? "error" : ""}
|
||||
placeholder="Enter your name"
|
||||
required
|
||||
/>
|
||||
{errors.name && <span className="error-message">{errors.name}</span>}
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="email">Email:</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
value={formData.email || ""}
|
||||
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
||||
className={errors.email ? "error" : ""}
|
||||
placeholder="user@example.com"
|
||||
/>
|
||||
{errors.email && <span className="error-message">{errors.email}</span>}
|
||||
</div>
|
||||
|
||||
<div className="form-actions">
|
||||
<button type="submit" disabled={status === "loading"}>
|
||||
{status === "loading" ? "Saving..." : "Save"}
|
||||
</button>
|
||||
<button type="button" onClick={() => setIsEditing(false)} className="secondary">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{errors.submit && <div className="alert alert-error">{errors.submit}</div>}
|
||||
</form>
|
||||
) : (
|
||||
<div className="user-details">
|
||||
<p>
|
||||
<strong>ID:</strong> {user.id}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Email:</strong> {user.email || "Not provided"}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Member since:</strong> {user.createdAt.toLocaleDateString()}
|
||||
</p>
|
||||
|
||||
<button onClick={() => setIsEditing(true)} className="edit-button">
|
||||
Edit Profile
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Export statements
|
||||
export {
|
||||
User,
|
||||
Theme,
|
||||
Status,
|
||||
LogLevel,
|
||||
Repository,
|
||||
ThemeProvider,
|
||||
UserProfile,
|
||||
fetchUserData,
|
||||
useLocalStorage,
|
||||
withLogging,
|
||||
debounce,
|
||||
}
|
||||
|
||||
export default ThemeProvider
|
||||
|
||||
// Type exports
|
||||
export type { User as UserType, ComponentType as ReactComponentType }
|
||||
Reference in New Issue
Block a user