Subversion Repositories VORC

Rev

Rev 138 | Rev 196 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 bgadell 1
#!/usr/bin/perl
2
 
3
# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)
4
my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";
5
close STDERR;
6
open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";
7
#warn "Redirecting errors to ${error_log_path}vorc_error.log";
8
 
9
#if ($ENV{SHELL}) { die "This script shouldn't be executed from the command line!\n"; }
10
 
11
#use strict;
12
use cPanelUserConfig;
13
use CGI qw/param cookie header start_html url/;
14
use HTML::Tiny;
15
use tableViewer;
16
use RollerCon;
17
use DateTime;
18
#use DateTime::Duration;
19
my $now = DateTime->now (time_zone => 'America/Los_Angeles');
20
our $h = HTML::Tiny->new( mode => 'html' );
21
 
22
my $cookie_string;
23
our ($EML, $PWD, $LVL);
24
my $user;
25
my $username;
26
my $RCid;
27
my $RCAUTH_cookie;
28
my $YEAR = 1900 + (localtime)[5];
29
 
30
$cookie_string = authenticate(1) || die;
31
($EML, $PWD, $LVL) = split /&/, $cookie_string;
32
$user = getUser($EML);
33
$user->{department} = convertDepartments $user->{department};
34
$username = $h->a ({ href=>"/schedule/view_user.pl?submit=View&RCid=$user->{RCid}" }, $user->{derby_name});
35
$RCid = $user->{RCid};
36
$RCAUTH_cookie = CGI::Cookie->new(-name=>'RCAUTH',-value=>"$cookie_string",-expires=>"+30m");
37
 
104 bgadell 38
if (!$user->{MVPid} and $LVL < RollerCon::ADMIN and $user->{department}->{MVP} < RollerCon::USER and $user->{department}->{COA} < RollerCon::USER) {
56 bgadell 39
	print header(-cookie=>$RCAUTH_cookie);
40
	printRCHeader("Unauthorized Page");
41
	print $h->div ({ class=>"error" }, "No Access");
42
	print $h->div ("Your user account is not registered to sign up for MVP Classes, so you can't see this page.  It's possible that your access is still being reviewed.  Please be patient.");
43
	print $h->a ({ href=>"/schedule/" }, "[Go Home]");
44
	print $h->close ("html");
45
	exit;
46
}
47
 
48
my $pageTitle = "MVP Classes";
49
my $prefscookie = "allnewmvpclasses";
50
our $DBTABLE = 'v_class';
51
my %COLUMNS = (
52
# colname   =>  [qw(DisplayName       N    type     status)],   status ->  static | default | <blank>
53
	name				=> [qw(Class         5    text     static )],
54
	date				=> [qw(Date         10    date              )],
55
	dayofweek		=> [qw(Day          15    select    default )],
56
	start_time	=> [qw(StartTime    20    text      )],
57
	end_time		=> [qw(EndTime      25    text       )],
58
	time				=> [qw(Time         30    text      default )],
59
	location		=> [qw(Track        35    select    default )],
65 bgadell 60
	level    		=> [qw(Level        37    select    default )],
56 bgadell 61
	coach				=> [qw(Coach        40    select    default )]
62
);
63
 
64
if ($LVL >= RollerCon::ADMIN) {
65
  $COLUMNS{id}       = [qw(Admin         1    none        default )];
66
	$COLUMNS{available}= [qw(SignUp       45    text       )]
67
}
68
 
104 bgadell 69
if ($LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::VOLUNTEER or $user->{department}->{COA} >= RollerCon::USER) {
112 - 70
	$COLUMNS{note}       = [qw(Notes         60    text         )],
71
	$COLUMNS{capacity}   = [qw(Capacity      65    number        default )],
72
	$COLUMNS{count}      = [qw(Count         70    number      default )],
73
	$COLUMNS{stars}      = [qw(Stars         75    number      default )],
74
	$COLUMNS{responses}  = [qw(Responses     80    number      default )],
56 bgadell 75
}
76
 
58 bgadell 77
if ($user->{MVPid} and $LVL < RollerCon::ADMIN) {
56 bgadell 78
	$COLUMNS{available}= [qw(SignUp       45    text       static)]
79
}
80
 
81
 
82
my $stylesheet = "/style.css";
83
my $homeURL = '/schedule/';
84
my @pagelimitoptions = ("All", 5, 10, 25);
85
 
86
# Set any custom "where" DB filters here...
87
my @whereClause;
88
 
89
# If we need to modify line item values, create a subroutine named "modify_$columnname"
90
#    It will receive a hashref to the object lineitem
91
 
92
#use WebDB;
93
#my $dbh = WebDB::connect;
94
my $dbh = getRCDBH;
95
 
96
sub modify_id {
97
  my $hr = shift;
98
  my $clicky = $hr->{count} ? "event.stopPropagation(); if (confirm('WARNING!\\nYou are modifying a class that someone has signed up for.')==true) {return true;} else {return false;}" : "return true;";
99
  my $extrawarning = $hr->{count} ? "\\nWARNING! It appears someone is signed up for it." : "";
100
  return join "&nbsp;", #$hr->{id},
101
         $h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Update", onClick=>$clicky }, "[Edit]"),
102
         $h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Copy" }, "[Copy]"),
103
         $h->a ({ href=>"view_class.pl?id=$hr->{id}&choice=Delete", onClick=>"event.stopPropagation(); if (confirm('Are you sure you want to DELETE this class?$extrawarning')==true) {return true;} else {return false;}" }, "[Delete]")
104
  ;
105
};
106
 
107
sub modify_available {
108
	my $t = shift;
109
 
110
 	my ($yyyy, $mm, $dd) = split /\-/, $t->{date};
111
	my $cutoff = DateTime->new(
112
        year => $yyyy,
113
        month => $mm,
114
        day => $dd,
115
        hour => 5,
116
        minute => 0,
117
        second => 0,
118
        time_zone => 'America/Los_Angeles'
119
  );
120
 
121
  return "CLOSED" unless $now < $cutoff;
122
 
123
	my $classkey = join '|', $t->{date}, $t->{start_time}, $t->{location};
124
 
80 bgadell 125
	($t->{signedup}) = $dbh->selectrow_array ("select role from v_class_signup where RCid = ? and id = ?", undef, $RCid, $t->{id} );
126
	my $droplink = $h->a ({ onClick=>"if (confirm('Really? You want to drop this class?')==true) { window.open('make_shift_change.pl?change=del&RCid=$RCid&id=$t->{id}&role=$t->{signedup}','Confirm Change','resizable,height=260,width=370'); return false; }" }, "[DROP]");
56 bgadell 127
	if (!$t->{available}) {
128
	  my $full = "FULL";
129
	  $full .= " | ".$droplink unless !$t->{signedup};
130
	  return $full;
131
  }
132
 
133
	$t->{available} .= " Open";
134
  $t->{available} .= " | ".$droplink unless !$t->{signedup};
85 bgadell 135
  if (findConflict ($ORCUSER->{RCid}, $t->{id}, "class")) {
87 bgadell 136
    $t->{available} .= " | *schedule conflict*" unless $t->{signedup};
85 bgadell 137
  } elsif (signUpEligible ($ORCUSER, $t, "class")) {
56 bgadell 138
		# SIGN UP
73 bgadell 139
		$t->{available} .= " | ".$h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=add&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[SIGN UP]");
56 bgadell 140
	}
58 bgadell 141
	if ($LVL > 4 or $user->{department}->{VCI} >= 2) {
56 bgadell 142
		# ADD USER
143
		$t->{available} ? $t->{available} .= " | " : {};
73 bgadell 144
		$t->{available} .= $h->a ({ onClick=>"event.stopPropagation(); window.open('make_shift_change.pl?change=lookup&RCid=$RCid&id=$classkey','Confirm Class Change','resizable,height=260,width=370'); return false;" }, "[ADD USER]");
56 bgadell 145
	}
146
 
147
	return $t->{available};
148
}
149
 
150
sub filter_available {
151
  my $colName = shift;
152
	my $filter = shift;
153
 
154
	if (defined $filter)	{
155
		if ($filter eq "Full") {
156
			return "$colName = 0";
157
		}
158
		return "$colName > 0";
159
	}	else {
160
		my $thing = "filter-${colName}";
161
		my $Options = "<OPTION></OPTION>"."<OPTION>Available</OPTION>"."<OPTION>Full</OPTION>";
162
 
163
		$Options =~ s/>($FORM{$thing})/ selected>$1/;
164
		return "<SELECT name=filter-${colName} $onChange>$Options</SELECT>";
165
	}
166
}
167
 
168
sub modify_time {
169
  my $t = shift;
170
  return convertTime $t->{time};
171
}
172
 
173
sub modify_start_time {
174
  my $t = shift;
175
  return convertTime $t->{start_time};
176
}
177
 
178
sub modify_end_time {
179
  my $t = shift;
180
  return convertTime $t->{end_time};
181
}
182
 
112 - 183
sub modify_stars {
184
  my $t = shift;
185
  if ($t->{coach} eq $user->{derby_name} or $LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::MANAGER) {
186
    $t->{stars} = $t->{stars};
187
  } else {
188
    $t->{stars} = '&nbsp;';
189
  }
190
}
56 bgadell 191
 
112 - 192
sub modify_responses {
193
  my $t = shift;
194
  if ($t->{coachRCid} == $user->{RCid} or $LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::MANAGER) {
195
    $t->{responses} = $t->{responses} // '0';
196
  } else {
197
    $t->{responses} = '&nbsp;';
198
  }
199
}
200
 
201
 
56 bgadell 202
# Ideally, nothing below this comment needs to change
203
#-------------------------------------------------------------------------------
204
 
205
 
206
our %NAME              = map  { $_ => $COLUMNS{$_}->[0] } keys %COLUMNS;
207
our %colOrderHash      = map  { $_ => $COLUMNS{$_}->[1] } keys %COLUMNS;
208
our %colFilterTypeHash = map  { $_ => $COLUMNS{$_}->[2] } keys %COLUMNS;
209
our @staticFields      = sort byfield grep { $COLUMNS{$_}->[3] eq 'static' } keys %COLUMNS;
210
our @defaultFields     = sort byfield grep { defined $COLUMNS{$_}->[3] } keys %COLUMNS;
211
#our @defaultFields     = grep { $COLUMNS{$_}->[3] eq 'default' or inArray ($_, \@staticFields) } keys %COLUMNS;
212
 
213
our @allFields = sort byfield keys %NAME;
214
our @displayFields = ();
215
our @hideFields = ();
216
my $QUERY_STRING;
217
 
218
my $pagelimit = param ("limit") // "All"; #$pagelimitoptions[$#pagelimitoptions];
219
my $curpage = param ("page") // 1;
220
 
221
our %FORM;
222
my $FILTER;
223
foreach (param()) {
224
 	if (/^year$/) { #
225
		$YEAR = param($_);
226
		next;
227
	}
228
 
229
	$FORM{$_} = param($_);				# Retrieve all of the FORM data submitted
230
 
231
	if ((/^filter/) and ($FORM{$_} ne '')) {	# Build a set of filters to apply
232
		my ($filter,$field) = split /-/, $_;
233
		$FILTER->{$field} = $FORM{$_} unless notInArray ($field, \@allFields);
234
	}	elsif ($FORM{$_} eq "true")	{		# Compile list of fields to display
235
	  if ($_ ne "shiftinclude") {
236
		  push @displayFields, $_;
237
		}
238
	}
239
}
240
 
241
push @whereClause, "year(date) = '$YEAR'";
242
 
243
if (exists $FORM{autoload})	{			# If the FORM was submitted (i.e. the page is being redisplayed),
244
							                    #  	build the data for the cookie that remembers the page setup
245
	my $disFields = join ":", @displayFields;
246
	my $fils = join ":", map { "$_=$FILTER->{$_}" } keys %{$FILTER};
247
 
248
	$QUERY_STRING = $disFields.'&'.$fils.'&'.$FORM{sortby}.'&'.$FORM{autoload}.'&'.$FORM{shiftinclude};
249
}
250
 
251
 
252
if (!(exists $FORM{autoload}))	{			# No FORM was submitted...
253
	if (my $prefs = cookie ($prefscookie) and !defined param ("ignoreCookie"))	{ # Check for cookies from previous visits.
254
		my ($disF, $filts, $sb, $al, $si) = split /&/,$prefs;
255
		@displayFields = split /:/,$disF;
256
 
257
		foreach my $pair (split /:/, $filts)	{
258
			my ($key, $value) = split /=/, $pair;
259
			$FORM{"filter-$key"} = $value;
260
			$FILTER->{$key} = $value;
261
		}
262
 
263
		$FORM{sortby} = $sb;
264
		$FORM{autoload} = $al;
265
		$FORM{shiftinclude} = $si;
266
		$QUERY_STRING = $prefs;
267
	}	else {
268
	  @displayFields = @defaultFields; # Otherwise suppply a default list of columns.
269
	  $FORM{autoload} = 1;             # And turn aut0load on by default.
270
		$FORM{sortby} = "note";
271
	}
272
}
273
 
274
# let's just make sure the columns are in the right order (and there aren't any missing)
275
@displayFields = grep { inArray($_, \@allFields) } sort byfield uniq @displayFields, @staticFields;
276
 
277
# If the field isn't in the displayFields list,	then add it to the hideFields list
278
@hideFields = grep { notInArray ($_, \@displayFields) } @allFields;
279
 
280
# Process any filters provided in the form to pass to the database
281
push @whereClause, map { filter ($_, $FILTER->{$_}) } grep { defined $FILTER->{$_} } @displayFields;
282
push @whereClause, "year(date) = '$YEAR'";
283
#warn join " and ", @whereClause;
284
 
285
							#  Given the fields to display and the where conditions,
286
							#	  "getData" will return a reference to an array of
287
							#	  hash references of the results.
288
my ($data, $datacount) = getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit);
289
my @ProductList = @{ $data };
290
 
291
#my @ProductList = @{ getData (\@displayFields, \@whereClause, $DBTABLE, $FORM{sortby}, $curpage, $pagelimit) };
292
my $x = scalar @ProductList; # How many results were returned?
293
 
294
# If the user is trying to download the Excel file, send it to them and then exit out.
295
if ($FORM{excel}) {
296
  exportExcel (\@ProductList, "MVP_Class_List");
297
  exit;
298
}
299
 
300
my @shifts;
301
if ($FORM{shiftinclude} eq "true") {
302
  my @SIWhere; # = ("year(date) = '$YEAR'");
153 - 303
  push @SIWhere, "year(date) = year(now())";
56 bgadell 304
  push @SIWhere, "RCid = $ORCUSER->{RCid}";
95 bgadell 305
  my ($d, $c) = getData (\@displayFields, \@SIWhere, 'v_class_signup', 'date');
56 bgadell 306
  @shifts = @{ $d };
307
}
308
 
138 - 309
my $signedOnAs = $username ? "Welcome, $username. ".$h->a ({ href=>"index.pl?LOGOUT" }, "[Log Out]") : "You are not signed in.";
56 bgadell 310
 
311
# Set some cookie stuff...
65 bgadell 312
my $path = `dirname $ENV{SCRIPT_NAME}`; chomp $path; $path .= '/' unless $path eq "/";
56 bgadell 313
my $queryCookie = cookie(-NAME=>$prefscookie,
314
			-VALUE=>"$QUERY_STRING",
315
			-PATH=>"$path",
316
			-EXPIRES=>'+365d');
317
 
318
my $SIChecked;
319
if ($FORM{shiftinclude}) {
320
  $SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", checked=>[], onClick=>'submit();' });
321
} else {
322
  $SIChecked = $h->input ({ type=>"checkbox", name=>"shiftinclude", value=>"true", onClick=>'submit();' });
323
}
324
 
325
# Print the header
326
print header(-cookie=>[$RCAUTH_cookie,$queryCookie]);
327
 
328
# 	print "<!-- FORM \n\n";				# Debug code to dump the FORM to a html comment
329
#	print "I'm catching updates!!!\n\n";
330
#	foreach $key (sort (keys %FORM))		#	Must be done after the header is written!
331
# 		{ print "\t$key:  $FORM{$key}\n"; }
332
# 	print "--> \n\n";
333
#
334
#
335
# 	print "<!-- ENV \n\n";				# Debug code to dump the ENV to a html comment
336
# 	foreach $key (sort (keys %ENV))			#	Must be done after the header is written!
337
# 		{ print "\t$key:  $ENV{$key}\n"; }
338
# 	print "--> \n\n";
339
#
340
# 	print "\n\n\n\n<!-- $QUERY_STRING --> \n\n\n\n";
341
 
342
 
343
#------------------
344
 
345
# Toggle the autoload fields within the table elements
346
our ($onClick, $onChange);   # (also used in scanFunctions)
347
my ($radiobutton, $refreshbutton, $sortby);
348
if ($FORM{autoload}) {
349
	$onClick = "onClick='submit();'";
350
	$onChange = "onChange='page.value = 1; submit();'";
351
  $radiobutton = $h->div ({ class=>'autoload' },
352
    ["Autoload Changes: ",
353
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();', checked=>[] }), "On ",
354
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();' }), "Off ",
355
    ]);
356
  $refreshbutton = "";
357
  $sortby = $h->select ({name=>"sortby", onChange=>'submit();' }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
358
} else {
359
  $onClick = "";
360
	$onChange = "onChange='page.value = 1;'";
361
  $radiobutton = $h->div ({ class=>'autoload' },
362
    ["Autoload Changes: ",
363
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>1, onClick=>'submit();' }), "On ",
364
    $h->input ({ type=>"radio", name=>'autoload', class=>'accent', value=>0, onClick=>'submit();', checked=>[] }), "Off ",
365
    ]);
366
  $refreshbutton = $h->input ({ type=>"button", value=>"Refresh", onClick=>"submit(); return false;" });
367
  $sortby = $h->select ({name=>"sortby" }, [ map { $FORM{sortby} eq $_ ? $h->option ({ value=>$_, selected=>[] }, $NAME{$_}) : $h->option ({ value=>$_ }, $NAME{$_}) } @displayFields ]);
368
}
369
 
370
print start_html (-title => $pageTitle, -style => {'src' => $stylesheet} );
371
 
372
print $h->open ('form', { action=>url, method=>'POST', name=>'Req' });
373
print $h->input ({ type=>"hidden", name=>"excel", value=>0 });
374
print $h->div ({ class => "accent pageheader" }, [
375
  $h->h1 ($pageTitle),
376
  $h->div ({ class=>"sp0" }, [
377
    $h->div ({ class=>"spLeft" }, [
378
      $radiobutton
379
    ]),
380
    $h->div ({ class=>"spRight" }, [
381
      $h->input ({ type=>"button", value=>"Home", onClick=>"window.location.href='$homeURL'" }),
382
      $refreshbutton
383
    ]),
384
  ]),
385
]);
386
 
387
# Print the Hidden fields' check boxes (if there are any)
388
 
389
my $c = 1;
390
my @hiddencheckboxes;
391
my @hiddenrows;
392
foreach my $field (sort { $NAME{$a} cmp $NAME{$b}; } @hideFields) {
393
  if ($FORM{autoload}) {
394
    push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.click();" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation(); submit();" }), $NAME{$field} ]);
395
  } else {
396
    push @hiddencheckboxes, $h->div ({ class=>'rTableCell quarters nowrap', onClick=>"Req.$field.checked=!Req.$field.checked;" }, [ $h->input ({ type=>'checkbox', class=>'accent', name=>$field, value=>'true', onClick=>"event.stopPropagation();" }), $NAME{$field} ]);
397
  }
398
  if ($c++ % 4 == 0) {
399
    push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]);
400
    @hiddencheckboxes = [];
401
  }
402
}
403
push @hiddenrows, $h->div ({ class=>'rTableRow' }, [ @hiddencheckboxes ]) unless --$c % 4 == 0;
404
 
405
my @yearoptions;
406
foreach (@{&getYears()}) {
407
	push @yearoptions, $YEAR eq $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_);
408
}
409
 
410
if (scalar @hideFields) {
411
  my @topleft;
412
  push @topleft, $h->div ({ class=>"nowrap" }, "Hidden Columns:");
413
  push @topleft, $h->div ({ class=>'rTable' }, [ @hiddenrows ]);
414
 
415
  print $h->div ({ class=>"sp0" }, [
416
    $h->div ({ class=>"spLeft"  }, [ @topleft ]),
417
    $h->div ({ class=>"spRight" }, [
418
      $signedOnAs, $h->br,
419
      "Show my classes: ", $SIChecked, $h->br,
420
      $h->input ({ type=>"button", value=>"Block Personal Time", onClick=>"window.location.href='personal_time.pl'" }),
421
    ])
422
  ]);
423
}
424
 
425
# Print the main table...............................................
426
 
427
print $h->open ('div', { class=>'rTable' });
428
 
429
my @tmptitlerow;
430
foreach my $f (@displayFields)	{  # Print the Column headings
431
  if (inArray ($f, \@staticFields)) {
432
    push @tmptitlerow, $h->div ({ class=>'rTableHead' }, [ $h->input ({ type=>"hidden", name=>$f, value=>"true" }), $NAME{$f} ]);
433
  } else {
434
    if ($FORM{autoload}) {
435
      push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.click();" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>'event.stopPropagation(); submit();' }), $NAME{$f} ]);
436
    } else {
437
      push @tmptitlerow, $h->div ({ class=>'rTableHead', onClick=>"Req.$f.checked=!Req.$f.checked;" }, [ $h->input ({ type=>"checkbox", class=>"accent", name=>$f, value=>"true", checked=>[], onClick=>"event.stopPropagation();" }), $NAME{$f} ]);
438
    }
439
  }
440
}
441
 
442
# Print the filter boxes...
443
print $h->div ({ class=>'rTableHeading' }, [ @tmptitlerow ], [ map { $h->div ({ class=>'rTableCell filters' }, filter ($_)) } @displayFields ], $h->div ({ class=>"rTableCell" }));
444
 
445
if ($FORM{shiftinclude}) {  # Include all of the user's shifts at the top
446
  foreach my $t (@shifts)	{
447
	  print $h->div ({ class=>'rTableRow highlighted' }, [ map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_} ? $t->{$_} : "") } @displayFields ]);
448
  }
449
  print $h->hr ({ width=>"500%" });
450
}
451
 
452
# Print the things
453
foreach my $t (@ProductList)	{
454
  my @display = map { $h->div ({ class=>'rTableCell' }, exists &{"modify_".$_} ? &{"modify_".$_} ($t) : $t->{$_}) } @displayFields;
112 - 455
  if ($LVL >= RollerCon::ADMIN or $user->{department}->{MVP} >= RollerCon::VOLUNTEER or $user->{department}->{COA} >= RollerCon::VOLUNTEER) {
56 bgadell 456
    print $t->{signedup} ? $h->div ({ class=>'rTableRow highlighted', onclick=>"location.href='view_class.pl?id=$t->{id}&choice=View'" }, [ @display ])
457
                         : $h->div ({ class=>'rTableRow shaded',      onclick=>"location.href='view_class.pl?id=$t->{id}&choice=View'" }, [ @display ]);
458
  } else {
459
    print $t->{signedup} ? $h->div ({ class=>'rTableRow highlighted' }, [ @display ])
460
                         : $h->div ({ class=>'rTableRow shaded' },      [ @display ]);
461
  }
462
}
463
 
464
print $h->close ('div');
465
 
466
# close things out................................................
467
 
468
my $pages = $pagelimit eq "All" ? 1 : int( $datacount / $pagelimit + 0.99 );
469
if ($curpage > $pages) { $curpage = $pages; }
470
 
471
my @pagerange;
472
if ($pages <= 5 ) {
473
  @pagerange = 1 .. $pages;
474
} else {
475
  if ($curpage <= 3) {
476
    @pagerange = (1, 2, 3, 4, ">>");
477
  } elsif ($curpage >= $pages - 2) {
478
    @pagerange = ("<<", $pages-3, $pages-2, $pages-1, $pages);
479
  } else {
480
    @pagerange = ("<<", $curpage-1, $curpage, $curpage+1, ">>");
481
  }
482
}
483
 
484
my @excelcode;
485
push @excelcode, $h->br;
486
push @excelcode, $h->a ({ href=>"", target=>"_new", onClick=>"window.document.Req.excel.value=1; window.document.Req.submit(); window.document.Req.excel.value=0; return false;" }, "[Export Displayed Data as an Excel Document.]");
487
 
488
print $h->br; # print $h->br;
489
print $h->div ({ class=>"sp0" }, [
490
    $h->div ({ class=>"spLeft" }, [
491
      $h->div ({ class=>"footer" }, [
492
        "To bookmark, save, or send this exact view, use the ",
493
        $h->a ({ href=>'', onClick=>"window.document.Req.method = 'GET'; Req.submit(); return false;" }, "[Full URL]"),
494
        $h->br,
495
        "If this page is displaying oddly, ", $h->a ({ href=>url ()."?ignoreCookie=1" }, "[Reset Your View]"),
496
        @excelcode,
497
        $h->br,
498
        "This page was displayed on ", currentTime (),
499
        $h->br,
65 bgadell 500
        "Please direct questions, problems, and concerns to $SYSTEM_EMAIL",
56 bgadell 501
        $h->br,
502
        "Displaying: ", $h->select ({ name=>"year", onchange=>"Req.submit();" }, [ @yearoptions ])
503
      ])
504
    ]),
505
    $h->div ({ class=>"spRight" }, [
506
      $h->h5 ([
507
               "$x of $datacount Record". ($x == 1 ? "" : "s") ." Displayed", $h->br,
508
               "Sorted by ", $sortby, $h->br,
509
               "Displaying ", $h->select ({ name=>"limit", onChange=>"page.value = 1; submit();" }, [ map { $pagelimit == $_ ? $h->option ({ selected=>[] }, $_) : $h->option ($_) } @pagelimitoptions ]), " Per Page", $h->br,
510
               ( $pages > 1 ? ( join " ", map { $_ == $curpage ? "<B>$_</b>" :
511
                                                $_ eq "<<"     ? $h->a ({ onClick=>qq{Req.page.value=1; Req.submit();} }, "$_") :
512
                                                $_ eq ">>"     ? $h->a ({ onClick=>qq{Req.page.value=$pages; Req.submit();} }, "$_") :
513
                                                                 $h->a ({ onClick=>qq{Req.page.value=$_; Req.submit();} }, "[$_]") } @pagerange ) : "" ), $h->br,
514
               $h->input ({ type=>"hidden", name=>"page", value=>$curpage })
515
      ])
516
    ]),
517
]);
518
 
519
print $h->close('form');
520
print $h->close('html');