28 - Refactor: User::default(), eliminate double-fetch, type currentAsset
This commit is contained in:
parent
7a17d4d90c
commit
27f0ac8568
4 changed files with 46 additions and 81 deletions
|
|
@ -6,7 +6,6 @@
|
|||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AssetController extends Controller
|
||||
{
|
||||
|
|
@ -19,13 +18,11 @@ public function index(): JsonResponse
|
|||
|
||||
public function current(): JsonResponse
|
||||
{
|
||||
// Get the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
$asset = $user ? $user->asset : null;
|
||||
$user = User::default();
|
||||
|
||||
return response()->json([
|
||||
'asset' => $asset,
|
||||
'price_tracking_enabled' => $user?->price_tracking_enabled ?? false,
|
||||
'asset' => $user->asset,
|
||||
'price_tracking_enabled' => $user->price_tracking_enabled,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -41,20 +38,7 @@ public function setCurrent(Request $request)
|
|||
$validated['full_name'] ?? null
|
||||
);
|
||||
|
||||
// Get or create the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
|
||||
if (! $user) {
|
||||
// Create a default user if none exists
|
||||
$user = User::create([
|
||||
'name' => 'Default User',
|
||||
'email' => 'user@example.com',
|
||||
'password' => 'password', // This will be hashed automatically
|
||||
'asset_id' => $asset->id,
|
||||
]);
|
||||
} else {
|
||||
$user->update(['asset_id' => $asset->id]);
|
||||
}
|
||||
User::default()->update(['asset_id' => $asset->id]);
|
||||
|
||||
return back()->with('success', 'Asset set successfully!');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,17 @@
|
|||
|
||||
class PricingController extends Controller
|
||||
{
|
||||
private User $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->user = User::default();
|
||||
}
|
||||
|
||||
public function current(): JsonResponse
|
||||
{
|
||||
// Get the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
$assetId = $user ? $user->asset_id : null;
|
||||
|
||||
$price = AssetPrice::current($assetId);
|
||||
|
||||
return response()->json([
|
||||
'current_price' => $price,
|
||||
'current_price' => AssetPrice::current($this->user->asset_id),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -30,17 +31,14 @@ public function update(Request $request)
|
|||
'price' => 'required|numeric|min:0.0001',
|
||||
]);
|
||||
|
||||
// Get the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
|
||||
if (! $user || ! $user->asset_id) {
|
||||
if (! $this->user->asset_id) {
|
||||
return back()->withErrors(['asset' => 'Please set an asset first.']);
|
||||
}
|
||||
|
||||
AssetPrice::updatePrice($user->asset_id, $validated['date'], $validated['price']);
|
||||
AssetPrice::updatePrice($this->user->asset_id, $validated['date'], $validated['price']);
|
||||
|
||||
if (! $user->price_tracking_enabled) {
|
||||
$user->update(['price_tracking_enabled' => true]);
|
||||
if (! $this->user->price_tracking_enabled) {
|
||||
$this->user->update(['price_tracking_enabled' => true]);
|
||||
}
|
||||
|
||||
return back()->with('success', 'Asset price updated successfully!');
|
||||
|
|
@ -48,27 +46,16 @@ public function update(Request $request)
|
|||
|
||||
public function history(Request $request): JsonResponse
|
||||
{
|
||||
// Get the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
$assetId = $user ? $user->asset_id : null;
|
||||
|
||||
$limit = $request->get('limit', 30);
|
||||
$history = AssetPrice::history($assetId, $limit);
|
||||
|
||||
return response()->json($history);
|
||||
return response()->json(AssetPrice::history($this->user->asset_id, $limit));
|
||||
}
|
||||
|
||||
public function forDate(Request $request, string $date): JsonResponse
|
||||
{
|
||||
// Get the first/default user (since no auth)
|
||||
$user = User::first();
|
||||
$assetId = $user ? $user->asset_id : null;
|
||||
|
||||
$price = AssetPrice::forDate($date, $assetId);
|
||||
|
||||
return response()->json([
|
||||
'date' => $date,
|
||||
'price' => $price,
|
||||
'price' => AssetPrice::forDate($date, $this->user->asset_id),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ public function asset(): BelongsTo
|
|||
return $this->belongsTo(Asset::class);
|
||||
}
|
||||
|
||||
public static function default(): self
|
||||
{
|
||||
return self::firstOrCreate(
|
||||
['email' => 'user@incr.local'],
|
||||
['name' => 'Default User', 'password' => 'password']
|
||||
);
|
||||
}
|
||||
|
||||
public function hasCompletedOnboarding(): bool
|
||||
{
|
||||
return $this->hasPurchases() && $this->hasMilestones();
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ interface Milestone {
|
|||
created_at: string;
|
||||
}
|
||||
|
||||
interface CurrentAsset {
|
||||
id: number;
|
||||
symbol: string;
|
||||
full_name: string | null;
|
||||
}
|
||||
|
||||
export default function Dashboard() {
|
||||
const [purchaseData, setPurchaseData] = useState<PurchaseSummary>({
|
||||
total_shares: 0,
|
||||
|
|
@ -41,7 +47,7 @@ export default function Dashboard() {
|
|||
const [activeForm, setActiveForm] = useState<'purchase' | 'milestone' | 'price' | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [needsOnboarding, setNeedsOnboarding] = useState(false);
|
||||
const [currentAsset, setCurrentAsset] = useState<any>(null);
|
||||
const [currentAsset, setCurrentAsset] = useState<CurrentAsset | null>(null);
|
||||
const [priceTrackingEnabled, setPriceTrackingEnabled] = useState(false);
|
||||
|
||||
// Fetch purchase summary, current price, milestones, and check onboarding
|
||||
|
|
@ -55,9 +61,13 @@ export default function Dashboard() {
|
|||
fetch('/assets/current'),
|
||||
]);
|
||||
|
||||
let totalShares = 0;
|
||||
let milestonesCount = 0;
|
||||
|
||||
if (purchaseResponse.ok) {
|
||||
const purchases = await purchaseResponse.json();
|
||||
setPurchaseData(purchases);
|
||||
totalShares = purchases.total_shares;
|
||||
}
|
||||
|
||||
if (priceResponse.ok) {
|
||||
|
|
@ -68,6 +78,7 @@ export default function Dashboard() {
|
|||
if (milestonesResponse.ok) {
|
||||
const milestonesData = await milestonesResponse.json();
|
||||
setMilestones(milestonesData);
|
||||
milestonesCount = milestonesData.length;
|
||||
}
|
||||
|
||||
if (assetResponse.ok) {
|
||||
|
|
@ -76,8 +87,7 @@ export default function Dashboard() {
|
|||
setPriceTrackingEnabled(assetData.price_tracking_enabled ?? false);
|
||||
}
|
||||
|
||||
// Check if onboarding is needed after all data is loaded
|
||||
await checkOnboardingStatus();
|
||||
setNeedsOnboarding(totalShares === 0 || milestonesCount === 0);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch data:', error);
|
||||
} finally {
|
||||
|
|
@ -88,33 +98,6 @@ export default function Dashboard() {
|
|||
fetchData();
|
||||
}, []);
|
||||
|
||||
// Check if user needs onboarding
|
||||
const checkOnboardingStatus = async () => {
|
||||
try {
|
||||
const [assetResponse, purchaseResponse, milestonesResponse] = await Promise.all([
|
||||
fetch('/assets/current'),
|
||||
fetch('/purchases/summary'),
|
||||
fetch('/milestones'),
|
||||
]);
|
||||
|
||||
const assetData = await assetResponse.json();
|
||||
const purchaseData = await purchaseResponse.json();
|
||||
const milestonesData = await milestonesResponse.json();
|
||||
|
||||
const hasAsset = !!assetData.asset;
|
||||
const hasPurchases = purchaseData.total_shares > 0;
|
||||
const hasMilestones = milestonesData.length > 0;
|
||||
|
||||
// User needs onboarding if any required step is missing
|
||||
const needsOnboarding = !hasPurchases || !hasMilestones;
|
||||
setNeedsOnboarding(needsOnboarding);
|
||||
} catch (error) {
|
||||
console.error('Failed to check onboarding status:', error);
|
||||
// If we can't check, assume onboarding is needed
|
||||
setNeedsOnboarding(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Refresh data after successful purchase
|
||||
const handlePurchaseSuccess = async () => {
|
||||
try {
|
||||
|
|
@ -211,10 +194,6 @@ export default function Dashboard() {
|
|||
|
||||
// Handle onboarding completion
|
||||
const handleOnboardingComplete = async () => {
|
||||
// Refresh all data and check onboarding status
|
||||
await checkOnboardingStatus();
|
||||
|
||||
// Refresh individual data sets
|
||||
const [purchaseResponse, priceResponse, milestonesResponse, assetResponse] = await Promise.all([
|
||||
fetch('/purchases/summary'),
|
||||
fetch('/pricing/current'),
|
||||
|
|
@ -222,9 +201,13 @@ export default function Dashboard() {
|
|||
fetch('/assets/current'),
|
||||
]);
|
||||
|
||||
let totalShares = 0;
|
||||
let milestonesCount = 0;
|
||||
|
||||
if (purchaseResponse.ok) {
|
||||
const purchases = await purchaseResponse.json();
|
||||
setPurchaseData(purchases);
|
||||
totalShares = purchases.total_shares;
|
||||
}
|
||||
|
||||
if (priceResponse.ok) {
|
||||
|
|
@ -235,6 +218,7 @@ export default function Dashboard() {
|
|||
if (milestonesResponse.ok) {
|
||||
const milestonesData = await milestonesResponse.json();
|
||||
setMilestones(milestonesData);
|
||||
milestonesCount = milestonesData.length;
|
||||
}
|
||||
|
||||
if (assetResponse.ok) {
|
||||
|
|
@ -242,6 +226,8 @@ export default function Dashboard() {
|
|||
setCurrentAsset(assetData.asset);
|
||||
setPriceTrackingEnabled(assetData.price_tracking_enabled ?? false);
|
||||
}
|
||||
|
||||
setNeedsOnboarding(totalShares === 0 || milestonesCount === 0);
|
||||
};
|
||||
|
||||
// Show onboarding if needed
|
||||
|
|
|
|||
Loading…
Reference in a new issue